الأمن
الإبلاغ عن الثغرات
عند الإبلاغ عن ثغرة، يصبح هذا الأمر أولويتنا الأولى، حيث يخصص لها مساهم بدوام كامل من أجل حلها. للإبلاغ عن ثغرة، يرجى إرسال بريد إلكتروني إلىsecurity@vuejs.org
على الرغم من أن الإبلاغ عن ثغرات جديدة نادر، إلا أننا نوصي أيضًا باستخدام أحدث إصدارات Vue ومكتباتها الرسمية لضمان أمان تطبيقك بأقصى درجة.
قاعدة رقم 1: لا تستخدم أي قوالب غير موثوق بها
القاعدة الأساسية الأكثر أمانًا عند استخدام Vue هي لا تستخدم أي محتوى غير موثوق به كقالب للمكون. فعل ذلك يعادل السماح بتنفيذ JavaScript عشوائي في تطبيقك - وأسوأ من ذلك، قد يؤدي إلى اختراق الخادم إذا تم تنفيذ الشفرة أثناء التصيير من جانب الخادم. مثال على استخدام مثل هذا الأمر:
js
Vue.createApp({
template: `<div>` + userProvidedString + `</div>` // لا تقم بهذا أبداً!
}).mount('#app')
تُصرف قوالب Vue إلى JavaScript، وتنفذ التعبيرات داخل القوالب كجزء من عملية التصيير. على الرغم من أن التعبيرات تُقيّم بالنسبة لسياق تصيير معين، بسبب تعقيد البيئات التنفيذية العامة المحتملة، فإنه من غير المنطقي لإطار عمل مثل Vue أن يحميك تمامًا من التنفيذ الخبيث للشيفرة دون تكلفة أداء غير واقعية. أسهل طريقة لتجنب هذا النوع من المشاكل هي التأكد من أن محتويات قوالب Vue الخاصة بك دائمًا موثوقة ويتحكم فيها بالكامل من قبلك.
ما الذي تقوم به Vue لحمايتك
محتوى الـHTML
سواء كنت تستخدم القوالب أو دوال التصيير، سيرشح المحتوى تلقائيا. وهذا يعني في هذا القالب:
template
<h1>{{ userProvidedString }}</h1>
إذ كان المتغير userProvidedString
يحتوي على:
js
'<script>alert("مرحبا")</script>'
سوف تحول إلى محتوى الـHTMl الموالي :
template
<script>alert("مرحبا")</script>
وبالتالي سنتجنب حقن الشيفرة. يرشح هذا باستخدام الواجهات البرمجية الأصلية للمتصفحات، مثل textContent
، لذا يمكن أن يكون هناك ثغرة فقط إذا كان المتصفح فيه ثغرة.
ربط السمات
بشكل مماثل، تصرف السمات الديناميكية أيضًا تلقائيا. وذلك يعني في هذا القالب:
template
<h1 :title="userProvidedString">
مرحباً
</h1>
إذ كان المتغير userProvidedString
يحتوي على:
js
'" onclick="alert(\'hi\')'
سوف تحول إلى محتوى الـHTMl الموالي :
template
" onclick="alert('مرحبا')
وبالتالي سنمنع السمة title
من حقن HTML جديد وغير محدد. يصرف هذا باستخدام الواجهات البرمجية الأصلية للمتصفحات، مثل setAttribute
، لذا يمكن أن يكون هناك ثغرة فقط إذا كان المتصفح فيه ثغرة.
المخاطر المحتملة
في أي تطبيق ويب، يكون السماح بتنفيذ المحتوى غير المصفّى والمقدم من المستخدم كـ HTML، CSS أو JavaScript خطرًا محتملا، لذا يجب تجنبه في أي مكان ممكن. ولكن هناك أوقاتا قد يكون فيها الخطر مقبولًا.
على سبيل المثال، تسمح خدمات مثل CodePen و JSFiddle بتنفيذ المحتوى المقدم من المستخدم، ولكن هذا في سياق يتوقع فيه ذلك ويحصره بشكل ما داخل إطارات. في حالات عندما يتطلب ميزة مهمة بشكل أساسي بعض المستويات من الضعف، فإنه من المسؤولية الخاصة بفريقك تحديد أهمية الميزة مقابل أسوأ حالات الضعف التي تُمكّنها.
حقن الـHTML
كما تعلمت في وقت سابق، ترشح Vue محتوى الـHTML تلقائيا، مما يمنعك من حقن HTML قابل للتنفيذ بشكل عرضي في تطبيقك. ومع ذلك، في حالات عندما تعرف أن المحتوى الـHTML آمن، يمكنك تصيير المحتوى الـHTML بشكل صريح:
باستخدام قالب:
template<div v-html="userProvidedHtml"></div>
باستخدام دالة التصيير:
jsh('div', { innerHTML: this.userProvidedHtml })
باستخدام دالة التصيير مع JSX:
jsx<div innerHTML={this.userProvidedHtml}></div>
تحذير
لا يمكن أبدًا الاعتماد على أن المحتوى الـHTML المقدم من المستخدم يكون 100% آمنًا إلا إذا كان في إطار محصور أو في جزء من التطبيق الذي يمكن أن يكون متاحًا للمستخدم الوحيد الذي كتب هذا الـHTML. بالإضافة إلى ذلك، السماح للمستخدمين بكتابة قوالب Vue الخاصة بهم سيجلب مخاطر مماثلة.
حقن عناوين URL
في عنوان URL مثل هذا:
template
<a :href="userProvidedUrl">
انقر على الرابط
</a>
هناك مشكلة أمنية محتملة إذا لم "يُنظف" العنوان URL لمنع تنفيذ JavaScript باستخدام javascript:
. هناك مكتبات مثل sanitize-url للمساعدة في ذلك، ولكن تجدر الملاحظة أنه: إذا كنت تقوم بتنظيف عناوين URL على الواجهة الأمامية، فأنت بالفعل تواجه مشكلة أمنية. يجب تنظيف عناوين URL المقدمة من المستخدم دائمًا من قبل الخادوم الخلفي قبل حفظها حتى في قاعدة البيانات. ثم تُتجنب المشكلة لـ كل عميل يتصل بالواجهة البرمجية الخاصة بك، بما في ذلك التطبيقات الأصلية للهواتف المحمولة. و تجدر الملاحظة أيضًا إلى أنه حتى مع عناوين URL المنظفة، لا يمكن لـ Vue مساعدتك في التأكد من أنها تؤدي إلى وجهات آمنة.
حقن التنسيقات
لنأخذ هذا المثال:
template
<a
:href="sanitizedUrl"
:style="userProvidedStyles"
>
انقر على الرابط
</a>
لنفترض أن sanitizedUrl
نُظف، لذلك إنه عنوان URL حقيقي وليس JavaScript. مع userProvidedStyles
، لا يزال للمستخدمين الخبيثين إمكانية تقديم CSS لـ "تخطي النقر"، على سبيل المثال تنسيق الرابط في مربع شفاف فوق زر "تسجيل الدخول". ثم إذا كان /https://user-controlled-website.com
مبنيًا ليشبه صفحة تسجيل الدخول لتطبيقك، فقد تكون قد أُخذت معلومات تسجيل الدخول الحقيقية للمستخدم.
قد تتمكن من تخيل إمكانية السماح للمحتوى المقدم من المستخدم لعنصر <style>
بإنشاء ثغرة أكبر بكثير، مما يعطي المستخدم التحكم الكامل في كيفية تنسيق الصفحة بأكملها. هذا هو السبب في أن Vue يمنع تصيير وسوم التنسيق داخل القوالب، مثل:
template
<style>{{ userProvidedStyles }}</style>
للحفاظ على مستخدميك آمنين تمامًا من تخطي النقر، نوصي بالسماح فقط بالتحكم الكامل في CSS داخل iframe محايد. بديلاً عن ذلك، عند تقديم التحكم للمستخدم من خلال وصلة التنسيق، نوصي باستخدام صياغة الكائن والسماح فقط للمستخدمين بتقديم قيم لخصائص محددة والتي يمكنهم التحكم فيها بأمان، مثل هذا:
template
<a
:href="sanitizedUrl"
:style="{
color: userProvidedColor,
background: userProvidedBackground
}"
>
انقر على الرابط
</a>
حقن شيفرة Javascript
ننصح بشدة بعدم تصيير عنصر <script>
مع Vue، لأن القوالب ودوال التصيير لا ينبغي أن يكون لها أي تأثيرات جانبية. ومع ذلك، هذه ليست الطريقة الوحيدة لتضمين السلاسل النصية التي ستقيم كـ JavaScript في وقت التشغيل.
في كل عنصر HTML يوجد سمات مع قيم تقبل سلاسل نصية من JavaScript، مثل onclick
، onfocus
، و onmouseenter
. ربط شيفرة الـJavaScript المقدمة من المستخدم إلى أي من هذه السمات الحدثية هي خطر أمني محتمل، لذلك يجب تجنبه.
تحذير
لا يمكن أن تُعتبر شيفرة JavaScript المقدمة من المستخدم 100٪ آمنة إلا إذا كانت في iframe محايد أو في جزء من التطبيق الذي يمكن أن يكون معرضًا فقط للمستخدم الذي كتب شيفرة JavaScript هذه.
في بعض الأحيان، نتلقى تقارير عن إمكانية الاختراقات البرمجية عبر مواقع الويب (XSS) في قوالب Vue. عمومًا، لا نعتبر هذه الحالات ثغرات أمنية حقيقية لأنه لا يوجد طريقة عملية لحماية المطورين من السيناريوهات التي تسمح بالاختراقات البرمجية عبر مواقع الويب:
يطلب المطور تصيير Vue للمحتوى غير المنقح المقدم من المستخدم كقوالب Vue. هذا غير آمن بشكل أساسي، ولا يوجد طريقة للتعرف على المصدر.
يقوم المطور بتثبيت Vue على صفحة HTML كاملة تحتوي على محتوى صُير من قبل الخادوم و مقدم من المستخدم. هذه نفس المشكلة الأساسية في #1، ولكن في بعض الأحيان قد يقوم المطورون بذلك دون وعي. ويمكن أن يؤدي هذا إلى ثغرات أمنية محتملة حيث يقدم المهاجم HTML آمنًا كـ HTML عادي وغير آمن كقالب Vue. أفضل ممارسة هي عدم تثبيت Vue على عناصر تحتوي على محتوى صير من قبل الخادم والمقدم من المستخدم.
الممارسات الجيدة
القاعدة العامة هي أنه إذا كنت تسمح بتنفيذ المحتوى غير المنقح المقدم من المستخدم (كـ HTML، JavaScript، أو حتى CSS)، فقد تعرض نفسك للهجمات. وهذه النصيحة صحيحة في الواقع سواء كنت تستخدم Vue أو إطار عمل آخر أو حتى لا تستخدم إطار عمل.
بالإضافة إلى التوصيات المذكورة أعلاه في المخاطر المحتملة، ننصحك أيضًا بالتعرف على المصادر التالية:
ثم استخدم ما تعلمته لمراجعة الشيفرة المصدرية للإعتماديات لديك للبحث عن أنماط خطيرة محتملة، إذا كان أيًا منها يتضمن مكونات طرف ثالث أو يؤثر على ما يصير إلى DOM.
التنسيق مع الواجهة الخلفية
تعالج ثغرات أمن HTTP مثل اختراقات تزوير الطلبات عبر مواقع الويب (CSRF/XSRF) والاختراقات البرمجية عبر مواقع الويب (XSSI) بشكل أساسي على الواجهة الخلفية، لذا ليست مشكلة في Vue. ومع ذلك، فإنه من المفيد التواصل مع فريق الواجهة الخلفية لتعلم كيفية التعامل بشكل أفضل مع الواجهة البرمجية الخاصة بهم، على سبيل المثال، عن طريق إرسال رموز CSRF مع إرسال النماذج.
التصيير من جانب الخادوم (SSR)
هناك بعض المخاوف الأمنية الإضافية عند استخدام التصيير من جانب الخادوم، لذا تأكد من اتباع أفضل الممارسات الموضحة في توثيق التصيير من جانب الخادوم لتجنب الثغرات.