الفرق بين المراجعتين ل"Rails/security"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
سطر 156: سطر 156:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== التزوير عبر الموقع (CSRF) ==
+
== تزوير الطلب عبر المواقع (CSRF) ==
تعمل طريقة الهجوم هذه على تضمين شفرة خبيثة أو ارتباط في صفحة تصل إلى تطبيق ويب يعتقد أن المستخدم قد عمل الاستيثاق عليها. إذا لم تنقضي مهلة جلسة تطبيق الويب، فقد ينفذ المهاجم أوامر غير مصرح بها.
+
تعمل طريقة الهجوم هذه على تضمين شفرة خبيثة أو ارتباط في صفحة تصل إلى تطبيق ويب يُعتقَد أن المستخدم قد أجرى استيثاقًا معه. إذا لم تنقضي مهلة جلسة تطبيق الويب، فقد ينفذ المهاجم أوامر غير مصرح بها.
  
في الفصل الدراسي، تعلمت أن معظم تطبيقات ريلز تستخدم جلسات تستند إلى ملفات تعريف الارتباط. إما أن تخزن معرف جلسة العمل في ملف تعريف الارتباط وأن تحتوي على تجزئة جلسة من جانب الخادم، أو أن تجزئة الجلسة بأكملها تكون على جانب العميل. في كلتا الحالتين، سيرسل المتصفح تلقائيًا ملف تعريف الارتباط على كل طلب إلى نطاق، إذا تمكن من العثور على ملف تعريف ارتباط لهذا النطاق. تكمن النقطة المثيرة للجدل في أنه إذا جاء الطلب من موقع لنطاق مختلف، سيرسل أيضًا ملف تعريف الارتباط. لنبدأ بمثال:
+
<nowiki>[[ملف:csrf_refactoring.png|بديل=رسم توضيحي لهجمات تزوير الطلب عبر المواقع (CSRF).|تصغير|رسم توضيحي لهجمات تزوير الطلب عبر المواقع (CSRF).]]</nowiki>
* يتصفح بوب لوحة الرسائل ويعرض مشاركة من أحد المتسللين حيث يوجد عنصر صورة HTML مهيأ. يشير العنصر إلى أمر في تطبيق إدارة مشروع Bob، بدلاً من ملف صورة:
+
 
<img src = "http://www.webapp.com/project/1/destroy">
+
في [[Rails/security#.D8.A7.D9.84.D8.AC.D9.84.D8.B3.D8.A7.D8.AA|فصل الجلسات]]، تعلمت أن معظم تطبيقات ريلز تستخدم جلسات تستند إلى ملفات تعريف الارتباط. إما أن تخزن معرف جلسة العمل في ملف تعريف الارتباط وأن تحتوي على [[Ruby/Hash|جدول Hash]] لجلسة من جانب الخادم، أو أن يكون [[Ruby/Hash|الجدول Hash]] بأكلمه للجلسة على جانب العميل. في كلتا الحالتين، سيرسل المتصفح تلقائيًا ملف تعريف الارتباط على كل طلب إلى نطاق إذا تمكن من العثور على ملف تعريف ارتباط لهذا النطاق. تكمن النقطة المثيرة للجدل في أنه إذا جاء الطلب من موقع لنطاق مختلف، سيرسل أيضًا ملف تعريف الارتباط. لنبدأ بمثال:
* لا تزال جلسة بوب على www.webapp.com على قيد الحياة، لأنه لم يقم بتسجيل الخروج قبل بضع دقائق.
+
* يتصفح محمد لوحة الرسائل ويعرض مشاركة من أحد القراصنة (hacker) حيث يوجد عنصر صورة HTML مهيأ. يشير العنصر إلى أمر في تطبيق إدارة مشروع محمد، بدلًا من ملف الصورة نفسها:<syntaxhighlight lang="html">
* من خلال عرض المشاركة، يجد المتصفح علامة صورة. يحاول تحميل الصورة المشتبه بها من www.webapp.com. كما أوضحنا من قبل، يرسل أيضًا على طول ملف تعريف الارتباط بمعرف الجلسة الصحيح.
+
<img src="http://www.webapp.com/project/1/destroy">
* يتحقق تطبيق الويب على www.webapp.com من معلومات المستخدم في تجزئة الجلسة المقابلة ويدمر المشروع بالمعرف 1. ثم يرجع صفحة نتائج غير متوقعة للذاكرة، لذا لن يعرض الصورة.
+
</syntaxhighlight>
* بوب لا يلاحظ الهجوم - ولكن بعد بضعة أيام اكتشف أن المشروع رقم واحد قد اختفى.
+
 
 +
* لا تزال جلسة محمد على www.webapp.com على قيد الحياة، لأنه لم يقم بتسجيل الخروج قبل بضع دقائق.
 +
* من خلال عرض المشاركة، يجد المتصفح وسم الصورة. يحاول تحميل الصورة المشتبه بها من www.webapp.com. كما أوضحنا من قبل، يرسل أيضًا على طول ملف تعريف الارتباط بمعرف الجلسة الصحيح.
 +
* يتحقق تطبيق الويب على www.webapp.com من معلومات المستخدم في جدول Hash للجلسة المقابلة ويدمر المشروع بالمعرف 1. ثم يعيد صفحة نتائج غير متوقعة للذاكرة، لذا لن تُعرَض الصورة.
 +
* محمد لا يلاحظ الهجوم - ولكن يكتشف بعد بضعة أيام أن المشروع رقم واحد قد اختفى.
 
من المهم ملاحظة أن الصورة أو الوصلة الفعلية لا يجب وضعها بالضرورة في نطاق تطبيق الويب، يمكن أن تكون في أي مكان - في منتدى أو مشاركة مدونة أو بريد إلكتروني.
 
من المهم ملاحظة أن الصورة أو الوصلة الفعلية لا يجب وضعها بالضرورة في نطاق تطبيق الويب، يمكن أن تكون في أي مكان - في منتدى أو مشاركة مدونة أو بريد إلكتروني.
  
يبدو CSRF نادرا جدا في CVE (نقاط الضعف والمشاكل الشائعة) - أقل من 0.1 ٪ في عام 2006 - ولكنه في الحقيقة "عملاق نائم" [غروسمان]. هذا في تناقض صارخ مع النتائج في العديد من أعمال المقاولات الأمنية - تعد CSRF مشكلة أمنية مهمة.
+
هجمات CSRF نادرةٌ جدًا في CVE (نقاط الضعف والمشاكل الشائعة)، إذ شكلت أقل من 0.1% من الهجمات في عام 2006، ولكنها في الحقيقة "عملاق نائم" (كما وصفها غروسمان[Grossman]). هذا في تناقض صارخ مع نتائج العديد من أعمال الاتفاقيات الأمنية، إذ تعد هجمات CSRF مشكلة أمنية خطيرة يجب الاهتمام بها.
  
 
=== إجراءات CSRF ===
 
=== إجراءات CSRF ===
ملاحظة: أولاً، كما هو مطلوب من قبل W3C، استخدم GET و POST بشكل مناسب. ثانيًا، سيحمي رمز الأمان في طلبات غير GET تطبيقك من CSRF.
+
'''ملاحظة''': أولًا، كما هو مطلوب من قبل W3C، استخدم طلبيات GET و POST بشكل مناسب. ثانيًا، سيحمي رمز الأمان في طلبيات غير GET تطبيقك من هجمات CSRF.
  
يوفر بروتوكول HTTP أساسًا نوعين رئيسيين من الطلبات - GET و POST (يجب استخدام DELETE و PUT و PATCH مثل POST). يوفر World Wide Web Consortium)W3C) قائمة تحقق لاختيار HTTP GET أو POST:
+
يوفر بروتوكول HTTP أساسًا نوعين رئيسيين من الطلبات هما: GET و POST (يجب استخدام DELETE و PUT و PATCH مثل POST). يوفر World Wide Web Consortium) W3C) قائمة تحقق لاختيار GET أو POST:
  
استخدم GET إذا:
+
استخدم GET إذا كان:
* يكون التفاعل أشبه بسؤال (بمعنى أنه عملية آمنة مثل الاستعلام أو قراءة العملية أو البحث).
+
* التفاعل أشبه بسؤال (بمعنى أنه عملية آمنة مثل الاستعلام أو قراءة العملية أو البحث).
استخدم POST إذا:
+
استخدم POST إذا كان:
 
* التفاعل أشبه بأمر، أو
 
* التفاعل أشبه بأمر، أو
* يغير التفاعل حالة المورد بطريقة يتصورها المستخدم (على سبيل المثال، اشتراك في خدمة)، أو
+
* التفاعل يغير حالة المورد بطريقة يتصورها المستخدم (على سبيل المثال، اشتراك في خدمة)، أو
* يُحمل المستخدم للمساءلة عن نتائج التفاعل.
+
* المستخدم يُحمَّل مسؤولية نتائج التفاعل.
إذا كان تطبيق الويب الخاص بك هو RESTful، فقد يستخدم لأفعال HTTP إضافية، مثل PATCH أو PUT أو DELETE. ولكن بعض متصفحات الويب القديمة لا تدعمها - فقط GET و POST. يستخدم ريلز حقل _method مخفي لمعالجة هذه الحالات.
+
إذا كان تطبيق الويب الخاص بك هو RESTful، فقد يُستخدَم لأفعال HTTP إضافية، مثل PATCH أو PUT أو DELETE. ولكن، بعض متصفحات الويب القديمة لا تدعمها بل تدعم فقط GET و POST. يستخدم ريلز الحقل ‎<code>_method</code> المخفي لمعالجة هذه الحالات.
 +
 
 +
يمكن إرسال طلبات POST تلقائيًا أيضًا. في هذا المثال، يُظهَر الرابط www.harmless.com كوجهة في شريط الحالة للمتصفح. ولكنه في الواقع أنشأ بشكل ديناميكي نموذجًا جديدًا يرسل طلب POST.<syntaxhighlight lang="html">
 +
<a href="http://www.harmless.com/" onclick="
 +
  var f = document.createElement('form');
 +
  f.style.display = 'none';
 +
  this.parentNode.appendChild(f);
 +
  f.method = 'POST';
 +
  f.action = 'http://www.example.com/account/destroy';
 +
  f.submit();
 +
  return false;">To the harmless survey</a>
 +
</syntaxhighlight>أو يضع المهاجم الرمز في معالج الحدث <code>onmouseover</code> الخاص بالصورة:<syntaxhighlight lang="html">
 +
<img src="http://www.harmless.com/img" width="400" height="400" onmouseover="..." />
 +
</syntaxhighlight>هناك العديد من الاحتمالات الأخرى، مثل استخدام الوسم <code>[[HTML/script|<script>]]</code> لتقديم طلب عبر الموقع إلى عنوان URL باستخدام استجابة JSONP أو [[JavaScript]]. الاستجابة هي تعليمات برمجية قابلة للتنفيذ يمكن للمهاجم العثور على طريقة لتنفيذها، وربما سرقة بيانات حساسة. للحماية من تسرب البيانات هذا، يجب علينا منع الوسم <code>[[HTML/script|<script>]]</code> عبر المواقع. ومع ذلك، فإن طلبات Ajax تلتزم بسياسة المتصفح نفسها (فقط يُسمح لموقعك ببدء <code>XmlHttpRequest</code>) حتى نتمكن من السماح لهم بإرجاع استجابات [[JavaScript]] بأمان.
 +
 
 +
'''ملاحظة''': لا يمكننا تمييز أصل الوسم <code>[[HTML/script|<script>]]</code> — سواء كان وسمًا على موقعك الخاص أو على موقع ضار آخر — لذا يجب علينا حظر جميع الوسوم <code>[[HTML/script|<script>]]</code>، حتى إذا كانت في الأصل آمنةً مثلها مثل الوسوم المحملة من موقعك الخاص. في هذه الحالات، تخطي حماية CSRF بشكل صريح من الإجراءات التي تخدم [[JavaScript]] الموجهة للوسم <code>[[HTML/script|<script>]]</code>.
 +
 
 +
للحماية من جميع الطلبات المزورة الأخرى، نقدم رمز الأمان المطلوب الذي يعرفه موقعنا ولكن المواقع الأخرى لا تعرفه. نحن نُضمِّن رمز الأمان في الطلبات ونتحقق منه على الخادم. إليك أحد الأسطر في وحدة تحكم التطبيق الخاص بك، والذي يُضمَّن بشكل افتراضي في تطبيقات ريلز التي أُنشئَت حديثًا:<syntaxhighlight lang="rails">
 +
protect_from_forgery with: :exception
 +
</syntaxhighlight>سيتضمن ذلك تلقائيًا رمزًا للأمان في جميع النماذج وطلبات Ajax التي أُنشئت بواسطة ريلز. إذا كان الرمز المميز للأمان لا يطابق ما كان متوقعًا، فسيرمى استثناء.
 +
 
 +
'''ملاحظة''': بشكل افتراضي، يتضمن ريلز محولًا للشيفرات البرمجية غير المزعجة ([https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts unobtrusive scripting adapter])، الذي يضيف ترويسةً تدعى <code>X-CSRF-Token</code> مع رمز الأمان على كل استدعاء Ajax ليس GET. بدون هذه الترويسة، لن تقبل ريلز طلبات Ajax التي ليست GET. عند استخدام مكتبة أخرى لإجراء استدعاءات Ajax، من الضروري إضافة رمز الأمان كعنوان افتراضي لاستدعاءات Ajax في مكتبتك. للحصول على الرمز، ألقِ نظرة على الوسم <code>‎<meta name='csrf-token' content='THE-TOKEN'>‎</code> المطبوع بواسطة <code><‎%= csrf_meta_tags %‎></code> في عرض التطبيق الخاص بك.
 +
 
 +
من الشائع استخدام ملفات تعريف الارتباط الدائمة لتخزين معلومات المستخدم، مع <code>cookies.permanent</code> على سبيل المثال. في هذه الحالة، لن تًمسَح ملفات تعريف الارتباط ولن تكون الإجراءات المتبعة للحماية من هجمات CSRF فعالة. إذا كنت تستخدم مخزن ملفات تعريف ارتباط مختلفًا عن الجلسة لهذه المعلومات، فيجب عليك التعامل مع ما تفعله بنفسك:<syntaxhighlight lang="rails">
 +
rescue_from ActionController::InvalidAuthenticityToken do |exception|
 +
  sign_out_user # Example method that will destroy the user cookies
 +
end
 +
</syntaxhighlight>يمكن وضع التابع أعلاه في <code>ApplicationController</code> وسيُستدعَى عندما يكون رمز CSRF غير موجود أو غير صحيح على طلب غير GET.
 +
 
 +
لاحظ أن ثغرات البرمجة عبر المواقع (XSS) تتجاوز جميع إجراءات الحماية من هجمات CSRF. يتيح XSS للمهاجم الوصول إلى جميع العناصر في الصفحة، حتى يتمكن من قراءة رمز الأمان CSRF من نموذج أو إرسال النموذج مباشرةً. سنتطرق إلى هجمات XSS لاحقًا.
 +
 
 +
== إعادة التوجيه والملفات ==
 +
هناك فئة أخرى من الثغرات الأمنية تحيط باستخدام إعادة التوجيه والملفات في تطبيقات الويب.
 +
 
 +
=== إعادة التوجيه ===
 +
'''تحذير''': إعادة التوجيه في تطبيق الويب هو أداة للتكسير ذات شأن بخس (underestimated cracker tool): لا يمكن للمهاجم توجيه المستخدم إلى موقع يحوي فخًا له فقط، بل قد يؤدي أيضًا إلى إنشاء هجوم قائم بذاته.
 +
 
 +
عندما يُسمَح للمستخدم بتمرير عنوان URL (أو جزءًا منه) لإعادة التوجيه، فمن المحتمل أن يكون عرضة للخطر. قد يكون الهجوم الأكثر وضوحًا هو إعادة توجيه المستخدمين إلى تطبيق ويب مزيف يبدو تمامًا كالتطبيق الأصلي. هذا الهجوم المزيف يسمى التصيد الاحتيالي (phishing attack) ويعمل عن طريق إرسال رابط غير مريب في رسالة بريد إلكتروني إلى المستخدمين عن طريق إدخال رابط XSS في تطبيق الويب أو وضع الرابط في موقع خارجي. إنه غير مثير للشك، لأنَّ الرابط يبدأ بعنوان URL إلى تطبيق الويب ويخفي عنوان URL للموقع الخبيث في معامل إعادة التوجيه مثل: http://www.example.com/site/redirect?to=www.attacker.com. في ما يلي مثال على إجراء قديم:<syntaxhighlight lang="rails">
 +
def legacy
 +
  redirect_to(params.update(action:'main'))
 +
end
 +
</syntaxhighlight>سيؤدي هذا إلى إعادة توجيه المستخدم إلى الإجراء الرئيسي إذا حاول الوصول إلى إجراء قديم. كان الهدف هو الحفاظ على معاملات عنوان URL للإجراء القديم وتمريرها إلى الإجراء الرئيسي. ومع ذلك، يمكن استغلالها من قِبل المهاجم إذا تضمنت مفتاح مضيف في عنوان URL:<syntaxhighlight lang="text">
 +
http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com
 +
</syntaxhighlight>إذا كان في النهاية عنوان URL، فلن يكون من الممكن ملاحظته ويعيد توجيه المستخدم إلى مضيف attacker.com. سيكون الإجراء المضاد البسيط هو تضمين المعاملات المتوقعة فقط في الإجراء القديم (مرة أخرى نعود إلى أسلوب القائمة البيضاء، بدلًا من إزالة المعاملات غير المتوقعة). وإذا أعدت التوجيه إلى عنوان URL، فتحقق من ذلك باستخدام قائمة بيضاء أو تعبير عادي.
 +
 
 +
==== هجمات XSS القائمة بحد ذاتها ====
 +
هناك عملية إعادة توجيه أخرى تعتمد على هجمات XSS وتعمل في Firefox و Opera باستخدام بروتوكول البيانات. يعرض هذا البروتوكول محتوياته مباشرة في المتصفح ويمكن أن يكون أي شيء من HTML أو JavaScript إلى صور بأكملها:<syntaxhighlight lang="text">
 +
data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K
 +
 
 +
 
 +
</syntaxhighlight>هذا المثال عبارة عن شيفرة [[JavaScript]] مشفرة عبر Base64 تعرض مربع رسالة بسيط. في عنوان URL لإعادة التوجيه، يمكن للمهاجم إعادة التوجيه إلى عنوان URL هذا باستخدام التعليمة البرمجية الضارة فيه. كإجراء مضاد، لا تسمح للمستخدم بتزويد عنوان URL (أو أجزاء منه) المراد إعادة توجيهه إليه.
 +
 
 +
=== تحميل الملفات ===
 +
'''ملاحظة''': تأكد من أن تحميلات ملف لا تستبدل ملفات أخرى مهمة، وعالج ملفات الوسائط (media files) بشكل غير متزامن.
  
يمكن إرسال طلبات POST تلقائيًا أيضًا. في هذا المثال، يظهر الارتباط www.harmless.com كوجهة في شريط الحالة للمتصفح. ولكنها في الواقع أنشأت بشكل ديناميكي نموذجًا جديدًا يرسل طلب POST.
+
تسمح العديد من تطبيقات الويب للمستخدمين بتحميل ملفات على الخادم. يجب دومًا ترشيح أسماء الملفات، التي قد يختارها المستخدم (جزئيًا)، حيث يمكن للمهاجم استخدام اسم ملف ضار للكتابة فوق أي ملف على الخادم. إذا خزنت الملفات المحملة في ‎/var/www/uploads، وقام المستخدم بإدخال اسم ملف مثل "‎../../../etc/passwd"، فقد يكتب فوق (يستبدل) ملف مهم. بالطبع، سيحتاج مترجم روبي إلى الأذونات المناسبة للقيام بذلك، وهو سبب آخر لتشغيل خوادم الويب و خوادم قواعد البيانات والبرامج الأخرى كمستخدم يونكس ذي صلاحيات أقل.
  
<a href="<nowiki>&lt;nowiki&gt;http://www.harmless.com/&lt;/nowiki&gt;</nowiki>" onclick="
+
عند ترشيح أسماء ملفات التي يدخلها المستخدم، لا تحاول إزالة الأجزاء الضارة. فكر في موقف يزيل فيه تطبيق الويب كافة الأجزاء "‎../‎" في اسم الملف ويستخدم المهاجم سلسلة مثل "‎....//‎"، إذ ستكون النتيجة "‎../‎". من الأفضل استخدام أسلوب القائمة البيضاء الذي يتحقق من صحة اسم الملف مع مجموعة من المحارف المقبولة. هذا يعارض نهج القائمة السوداء الذي يحاول إزالة الأحرف غير المسموح بها. في حالة عدم وجود اسم ملف صالح، ارفضه (أو استبدل المحارف غير المقبولة)، ولكن لا تزله. إليك اسم الملف المطهَّر من الإضافة [https://github.com/technoweenie/attachment_fu/tree/master attachment_fu]:<syntaxhighlight lang="rails">
 var f = document.createElement('form');
+
def sanitize_filename(filename)
 f.style.display = 'none';
+
  filename.strip.tap do |name|
 this.parentNode.appendChild(f);
+
    # بشكل صحيح مع مسارات ويندوز على لينكس File.basename ملاحظة: لا يعمل
 f.method = 'POST';
+
    # لذا اجلب اسم الملف فقط دون كامل المسار
 f.action = '<nowiki>&lt;nowiki&gt;http://www.example.com/account/destroy'&lt;/nowiki&gt;</nowiki>;
+
    name.sub! /\A.*(\\|\/)/, ''
 f.submit();
+
    # أخيرًا، بدل شرطات سفلية مكان المحارف غير الأبجدية أو الرقمية أو 
 return false;">To the harmless survey</a>
+
    # الشرطات السفلية أو النقط
 +
    name.gsub! /[^\w\.\-]/, '_'
 +
  end
 +
end
  
أو يضع المهاجم الرمز في معالج الأحداث onmouseover الخاص بالصورة:
+
</syntaxhighlight>هناك عيب كبير في المعالجة المتزامنة لعمليات تحميل الملفات (كما تفعل الإضافة [https://github.com/technoweenie/attachment_fu/tree/master attachment_fu] مع الصور) هو ضعفه تجاه هجمات حجب الخدمة (denial-of-service attacks). يمكن للمهاجم بدء تحميل ملفات الصور بشكل متزامن من العديد من أجهزة الكمبيوتر مما يزيد من حمل الخادم وقد يؤدي إلى تعطيل الخادم أو إبطائه.
  
<img src="http://www.harmless.com/img" width="400" height="400" onmouseover="..." />
+
الحل الأفضل لذلك هو معالجة ملفات الوسائط بشكل غير متزامن: احفظ ملف الوسائط وجدول طلب معالجة في قاعدة البيانات. ستأتي بعدئذٍ عملية أخرى وتعالج الملف في الخلفية.
 +
 
 +
=== الشيفرات البرمجية القابلة للتنفيذ في الملفات المحملة ===
 +
'''تحذير''': قد تُنفَّذ شيفرة مصدرية في الملفات المحملة عند وضعها في مجلدات محددة. لا تضع الملفات المحملة في المجلد public/ لريلز إذا كان هو مجلد Apache الرئيسي.
 +
 
 +
يحتوي خادم الويب الشهير Apache على خيار يسمى <code>DocumentRoot</code>. هذا هو المجلد الرئيسي لموقع الويب، وسيُخدَّم كل شيء في شجرة هذا المجلد بواسطة خادم الويب. إذا كانت هناك ملفات ذات امتداد (لاحقة) معين، تُنفذ التعليمة البرمجية الموجودة بها عند الطلب (قد يتطلب ذلك تعيين بعض الخيارات). ومن أمثلة ذلك ملفات PHP و CGI. فكر الآن في موقف يُحمِّل فيه أحد المهاجمين ملفًا باسم "file.cgi" يحوي شيفرة فيه تُنفذ عندما يُنزِّل شخص ما الملف.
 +
 
 +
إذا كان الخيار DocumentRoot في خادم الويب Apache يشير إلى المجلد ‎/public لريلز، فلا تضع الملفات المحملة فيه، بل خزن الملفات في مستوى واحد لأعلى على الأقل.
 +
 
 +
=== تنزيل الملفات ===
 +
'''ملاحظة''': تأكد من عدم تمكن المستخدمين من تنزيل ملفات عشوائية.
 +
 
 +
مثلما يلزمك ترشيح أسماء الملفات المراد تحميلها، يجب عليك القيام بالأمر ذاته للملفات المراد تنزيلها. يرسل التابع <code>()send_file</code> ملفات من الخادم إلى العميل. إذا كنت تستخدم اسم الملف الذي أدخله المستخدم، دون تصفية، فسيتمكن المستخدم من تنزيل أي ملف من خادمك:<syntaxhighlight lang="rails">
 +
send_file('/var/www/uploads/' + params[:filename])
 +
</syntaxhighlight>ما عليك سوى تمرير اسم ملف مثل "‎../../../etc/passwd" لتنزيل معلومات تسجيل الدخول الخاصة بالخادم. حل هذه المشكلة بسيط وهو التحقق من أن الملف المطلوب موجود في المجلد المتوقع:<syntaxhighlight lang="rails">
 +
basename = File.expand_path('../../files', __dir__)
 +
filename = File.expand_path(File.join(basename, @file.public_filename))
 +
raise if basename !=
 +
    File.expand_path(File.join(File.dirname(filename), '../../../'))
 +
send_file filename, disposition: 'inline'
 +
</syntaxhighlight>أسلوب آخر (إضافي) هو تخزين أسماء الملفات في قاعدة البيانات وتسمية الملفات الموجودة على القرص بعد المعرفات الموجودة في قاعدة البيانات. هذا أيضًا طريقة جيدة لتجنب تنفيذ شيفرة برمجية محتملة جرى تحميلها. تسلك الإضافة attachment_fu  نفس السلوك أيضًا ولكن بطريقة مشابهة.
 +
 
 +
== الإنترانت والأمان الإداري ==
 +
واجهات إدارة إنترانت هي أهداف هجوم شائعة، لأنها تسمح بالوصول المميز. على الرغم من أن هذا سيتطلب العديد من التدابير الأمنية الإضافية، فإن العكس هو الحال في العالم الحقيقي.
 +
 
 +
في عام 2007، كانت هناك أول طروادة مصممة خصيصًا والتي سرقت المعلومات من الإنترانت، وهي موقع الويب الخاص بـ "مونستر لأرباب العمل" لموقع Monster.com، وهو تطبيق ويب للتعيين عبر الإنترنت. تعد أحصنة طروادة المصممة خصيصًا نادرة جدًا حتى الآن، والمخاطر منخفضة جدًا، ولكنها بالتأكيد تمثل إمكانية ومثالًا على أهمية أمان مضيف العميل أيضًا. ومع ذلك، فإن التهديد الأعلى للتطبيقات الداخلية والإدارة هو XSS و CSRF.
 +
 
 +
XSS إذا كان التطبيق الخاص بك يعيد عرض مدخلات المستخدم الضار من الشبكة الخارجية، فسيكون التطبيق عرضة لـ XSS. أسماء المستخدمين، التعليقات، تقارير الرسائل غير المرغوب فيها، عناوين الطلبات هي مجرد أمثلة قليلة غير مألوفة، حيث يمكن أن يكون هناك XSS.
 +
 
 +
وجود مكان واحد في واجهة الإدارة أو الإنترانت، حيث لم تُطهر المدخلات، يجعل التطبيق بأكمله عرضة للخطر. تشمل عمليات الاستغلال المحتملة سرقة ملف تعريف الارتباط الخاص بالمسؤول، وحقن iframe لسرقة كلمة مرور المسؤول أو تثبيت برامج ضارة من خلال ثغرات أمنية للمتصفح لتولي جهاز الكمبيوتر الخاص بالمشرف.
 +
 
 +
ارجع إلى قسم الحقن للتعامل مع الإجراءات المضادة مقابل XSS.
 +
 
 +
التزوير عبر الموقع CSRF طلب التزوير (CSRF)، المعروف أيضا باسم التزوير المرجعي عبر المواقع (XSRF)، هو أسلوب هجوم عملاق، فإنه يسمح للمهاجم بالقيام بكل شيء قد يفعله المسؤول أو مستخدم الإنترانت. كما سبق أن رأينا أعلاه كيف يعمل CSR، إليك بعض الأمثلة لما يمكن أن يفعله المهاجمون في واجهة الإنترانت أو الإدارة.
 +
 
 +
مثال حقيقي هو إعادة تشكيل جهاز التوجيه بواسطة CSRF. أرسل المهاجمون بريدًا إلكترونيًا ضارًا، مع CSRF فيه، إلى المستخدمين المكسيكيين. زعم البريد الإلكتروني أن هناك بطاقة إلكترونية في انتظار المستخدم، ولكنها احتوت أيضًا على علامة صورة أدت إلى طلب HTTP-GET لإعادة تكوين جهاز توجيه المستخدم (وهو نموذج مشهور في المكسيك). غيَّر الطلب إعدادات نظام أسماء النطاقات (DNS) بحيث تعين طلبات موقع مصرفي مقره في المكسيك لموقع المهاجم. كل من وصل إلى الموقع المصرفي من خلال ذلك الراوتر رأى موقع المهاجم المزيّف على شبكة الإنترنت وسرقت أوراق اعتماده.
 +
 
 +
مثال آخر غير عنوان البريد الإلكتروني وكلمة مرور Google Adsense. إذا سُجل الضحية في جوجل أدسنس، واجهة الإدارة لحملات الإعلان جوجل، يستطيع المهاجم تغيير أوراق اعتماد الضحية.
 +
 
 +
هناك هجوم شائع آخر هو إرسال بريد إلكتروني غير مرغوب فيه إلى تطبيق الويب الخاص بك أو مدونتك أو المنتدى الخاص بك لنشر XSS ضار. بالطبع، يجب على المهاجم معرفة بنية عنوان URL، ولكن معظم عناوين URL Rails واضحة تمامًا أو يسهل اكتشافها، إذا كانت واجهة إدارية للتطبيق مفتوح المصدر. قد يخمن المهاجم 1000 تخمين محظوظ فقط من خلال تضمين علامات IMG الخبيثة التي تحاول إجراء كل تركيبة ممكنة.
 +
 
 +
للتدابير المضادة ضد CSRF في واجهات الإدارة والتطبيقات Intranet، ارجع إلى التدابير المضادة في قسم CSRF.
 +
 
 +
=== الاحتياطات الإضافية ===
 +
تعمل واجهة الإدارة العامة بالشكل التالي: إنها موجودة على www.example.com/admin، ولا يمكن الوصول إليها إلا إذا تعين علامة المشرف في نموذج المستخدم، وتعرض إعادة إدخال المستخدم وتسمح للمشرف بحذف / إضافة / تعديل أي شيء من البيانات المطلوبة. إليك بعض الأفكار حول هذا:
 +
* من المهم جدًا التفكير في أسوأ الحالات: ماذا لو كان شخص ما قد احتفظ بملفات تعريف الارتباط أو بيانات اعتماد المستخدم. يمكنك تقديم أدوار للواجهة الإدارية للحد من إمكانيات المهاجم. وماذا عن بيانات اعتماد تسجيل الدخول الخاصة لواجهة الإدارة، بخلاف تلك المستخدمة للجزء العام من التطبيق. أو كلمة مرور خاصة لاتخاذ إجراءات خطيرة للغاية؟
 +
* هل يجب على المشرف حقًا الوصول إلى الواجهة من كل مكان في العالم؟ نفكر في الحد من تسجيل الدخول إلى مجموعة من عناوين IP المصدر. افحص request.remote_ip لمعرفة عنوان IP للمستخدم. هذه ليست واقية من الرصاص، ولكن حاجز كبير. تذكر أنه قد يكون هناك بروكسي قيد الاستخدام.
 +
* ضع واجهة الإدارة على نطاق فرعي خاص مثل admin.application.com واجعله تطبيقًا منفصلاً مع إدارة المستخدم الخاصة به. هذا يجعل سرقة ملف تعريف ارتباط مسؤول من النطاق المعتاد، www.application.com، مستحيل. هذا بسبب نفس سياسة الأصل في المستعرض الخاص بك: قد لا يُقرأ البرنامج النصي الذي حُقن (XSS) على www.application.com ملف تعريف الارتباط لـ admin.application.com والعكس بالعكس.
 +
 
 +
== إدارة المستخدم ==
 +
يجب أن يتعامل كل تطبيق ويب تقريبًا مع التفويض والاستيثاق. وبدلاً من أن تتجول بنفسك، من المستحسن استخدام المكونات الإضافية الشائعة. ولكن ابقهم محدثين أيضًا. يمكن أن تؤدي بعض الاحتياطات الإضافية إلى جعل تطبيقك أكثر أمانًا.
 +
 
 +
هناك عدد من المكونات الإضافية للاستيثاق متاحة في Rails. هناك اخرى جيدة، مثل الاستنباط ومنطق الاستيثاق، تخزن فقط كلمات المرور المشفرة، وليس كلمات المرور ذات النص العادي. في Rails 3.1، يمكنك استخدام التابع has_secure_password المضمّن الذي يحتوي على ميزات مشابهة.
 +
 
 +
يحصل كل مستخدم جديد على رمز تنشيط لتفعيل حسابه عندما يتلقى رسالة إلكترونية تحتوي على رابط فيه. بعد تنشيط الحساب، تعين أعمدة activation_code إلي NULL في قاعدة البيانات. إذا طلب شخص ما عنوان URL كهذا، يُسجيل دخوله كأول مستخدم نشط موجود في قاعدة البيانات (ومن المحتمل أن يكون هذا هو المسؤول):
 +
 
 +
<nowiki>http://localhost:3006/user/activate</nowiki>
 +
 
 +
<nowiki>http://localhost:3006/user/activate?id=</nowiki>
 +
 
 +
هذا ممكن لأنه على بعض الخوادم، بهذه الطريقة، يكون معرف المعامل، كما هو الحال في [params [: id، لا شيء. ومع ذلك، هنا هو الباحث عن إجراء التنشيط:
 +
 
 +
User.find_by_activation_code(params[:id])
 +
 
 +
إذا كان المعامل لا شيء، فسيكون استعلام SQL الناتج
 +
 
 +
SELECT * FROM users WHERE (users.activation_code IS NULL) LIMIT 1
 +
 
 +
وبالتالي وجدت أول مستخدم في قاعدة البيانات، و أعادته وسجله. يمكنك معرفة المزيد عنه في هذا المنشور. من المستحسن تحديث المكونات الإضافية من وقت لآخر. علاوة على ذلك، يمكنك مراجعة طلبك للعثور على المزيد من العيوب على هذا النحو.
 +
 
 +
=== حسابات فرض الإجبار ===
 +
ملاحظة: هجمات القوة العمياء في الحسابات هي هجمات تجريبية وأخطاء على بيانات اعتماد تسجيل الدخول. صدهم مع المزيد من رسائل الخطأ العامة وربما تتطلب إدخال اختبار CAPTCHA.
 +
 
 +
قد يُساء استخدام قائمة بأسماء المستخدمين لتطبيق الويب الخاص بك لفرض كلمات المرور المقابلة، لأن معظم الأشخاص لا يستخدمون كلمات مرور معقدة. معظم كلمات المرور هي مزيج من الكلمات القاموس وربما الأرقام. إذا سُلحت بقائمة أسماء المستخدمين والقواميس، فقد يجد البرنامج التلقائي كلمة المرور الصحيحة في غضون دقائق.
 +
 
 +
وبسبب هذا، فإن معظم تطبيقات الويب تعرض رسالة خطأ عامة "اسم المستخدم أو كلمة المرور غير صحيحة"، إذا كان أحدها غير صحيح. إذا قال "لم يعثر على اسم المستخدم الذي ادخلته"، يمكن للمهاجم تلقائياً تجميع قائمة بأسماء المستخدمين.
 +
 
 +
ومع ذلك، ما يهمل معظم مصممي تطبيقات الويب، هي صفحات نسيت كلمة المرور. تعترف هذه الصفحات غالبًا بأن اسم المستخدم أو عنوان البريد الإلكتروني الذي أُدخل لم يعثر عليه. هذا يسمح للمهاجم بتجميع قائمة بأسماء المستخدمين والقوة العمياء للحسابات.
 +
 
 +
للتخفيف من مثل هذه الهجمات، اعرض رسالة خطأ عامة على صفحات نسيت كلمة المرور أيضًا. علاوة على ذلك، يمكنك طلب إدخال اختبار CAPTCHA بعد عدد من عمليات تسجيل الدخول الفاشلة من عنوان IP معين. ومع ذلك، لاحظ أن هذا ليس حلًا مضادًا للرصاص ضد البرامج التلقائية، لأن هذه البرامج قد تغير عنوان IP الخاص بها تمامًا كما هو الحال دائمًا. ومع ذلك، فإنه يثير حاجز الهجوم.
 +
 
 +
=== اختطاف الحساب ===
 +
تسهل العديد من تطبيقات الويب اختطاف حسابات المستخدمين. لماذا لا تكون مختلفة وجعلها أكثر صعوبة؟
 +
 
 +
==== كلمات السر ====
 +
فكر في الموقف الذي سرق فيه أحد المهاجمين ملف تعريف ارتباط جلسة المستخدم، ومن ثم يمكنه استخدام التطبيق. إذا كان من السهل تغيير كلمة المرور، سيختطف المهاجم الحساب بنقرات قليلة. أو إذا كان نموذج تغيير كلمة المرور عرضة لـ CSRF، سيغير المهاجم كلمة المرور الخاصة بالضحية عن طريق إغرائهم إلى صفحة ويب تحتوي على علامة IMG صُممت باستخدام CSRF. كإجراء مضاد، تأكد من أن نماذج كلمة مرور التغيير آمنة ضد CSRF، بالطبع. وتطلب من المستخدم إدخال كلمة المرور القديمة عند تغييرها.
 +
 
 +
==== البريد الإلكتروني ====
 +
ومع ذلك، قد يسيطر المهاجم أيضًا على الحساب عن طريق تغيير عنوان البريد الإلكتروني. بعد تغييرها، ينتقل إلى صفحة كلمة المرور المنسية وسترسل كلمة المرور (قد تكون جديدة) إلى عنوان البريد الإلكتروني للمهاجم. كإجراء مضاد، يطلب من المستخدم إدخال كلمة المرور عند تغيير عنوان البريد الإلكتروني أيضًا.
 +
 
 +
==== الآخرى ====
 +
اعتمادًا على تطبيق الويب الخاص بك، قد يكون هناك المزيد من الطرق لاختطاف حساب المستخدم. في العديد من الحالات، يساعد CSRF و XSS في القيام بذلك. على سبيل المثال، كما هو الحال في ثغرة CSRF في Google Mail. في هجوم إثبات المفهوم هذا، كان الضحية قد اغري إلى موقع ويب يسيطر عليه المهاجم. في هذا الموقع عبارة عن علامة IMG وضعت وينتج عنها طلب HTTP GET يغير اعدادات فلتر Google Mail. إذا سجل الضحية في Google Mail، سيغير المهاجم الفلاتر لإعادة توجيه جميع رسائل البريد الإلكتروني إلى عنوان البريد الإلكتروني الخاص بهم. هذا يماثل ضررًا تمامًا مثل اختطاف الحساب بالكامل. كتدبير مضاد، راجع منطق التطبيق الخاص بك وأزل كل ثغرات XSS و CSRF.
 +
 
 +
=== CAPTCHAs ===
 +
ملاحظة: اختبار CAPTCHA هو اختبار استجابة تحديدي لتحديد أن الاستجابة لا تُنشأ بواسطة جهاز كمبيوتر. وغالبًا ما يستخدم لحماية نماذج التسجيل من المهاجمين ونماذج التعليقات من برامج التتبع العشوائية التلقائية عن طريق مطالبة المستخدم بكتابة حروف صورة مشوهة. هذا هو اختبار CAPTCHA الإيجابي، ولكن هناك أيضًا اختبار CAPTCHA السلبي. إن فكرة اختبار CAPTCHA السلبي ليست للمستخدم أن يثبت أنه إنسان، ولكنه يكشف أن الروبوت هو إنسان آلي.
 +
 
 +
واجهة برمجة تطبيقات CAPTCHA إيجابية شائعة هي reCAPTCHA التي تعرض صورتين مشوهتين للكلمات من الكتب القديمة. كما أنه يضيف خطًا مائلًا، بدلاً من خلفية مشوهة ومستويات عالية من التشويش على النص كما كان يفعل اختبار CAPTCHA سابقًا، لأنه كُسرهذا الأخير. كمكافأة، يساعد استخدام reCAPTCHA في تحويل الكتب القديمة إلى رقمية. ReCAPTCHA هو أيضًا مكون إضافي Rails يحمل نفس اسم واجهة برمجة التطبيقات.
 +
 
 +
ستحصل على مفتاحين من واجهة برمجة التطبيقات (API)، عام ومفتاح خاص، يجب عليك وضعه في بيئة Rails لديك. بعد ذلك يمكنك استخدام التابع recaptcha_tags في الواجهة، و verification_recaptcha في وحدة التحكم. سيرجع  Verify_recaptcha خطأ إذا فشل التحقق من الصحة. تكمن المشكلة في CAPTCHA في أن لها تأثيرًا سلبيًا على تجربة المستخدم. بالإضافة إلى ذلك، وجد بعض المستخدمين المعاقين بصريًا أن بعض أنواع اختبارات CAPTCHA المشوهة يصعب قراءتها. ومع ذلك، تعد اختبارات CAPTCHA الإيجابية إحدى أفضل الطرق لمنع جميع أنواع برامج التتبع من إرسال النماذج.
 +
 
 +
معظم البوتات غبية حقا. إنهم يزحفون على الويب ويضعون بريدهم الإلكتروني غير المرغوب فيه في كل حقل يمكنهم العثور عليه. تستفيد اختبارات CAPTCHA السلبية من ذلك وتتضمن حقل "honeypot" في النموذج الذي سيخفي عن المستخدم البشري من خلال CSS أو جافا سكريبت.
 +
 
 +
تجدر الإشارة إلى أن اختبار CAPTCHA السلبي لا يكون فعالًا إلا ضد برامج التتبع البكم ولا يكفي لحماية التطبيقات المهمة من برامج التتبع المستهدفة. ومع ذلك، يمكن الجمع بين اختبار CAPTCHA السلبي والإيجابي لزيادة الأداء، على سبيل المثال، إذا لم يكن حقل "honeypot" فارغًا (اُكتشف)، فلن تحتاج إلى التحقق من اختبار CAPTCHA الإيجابي، والذي يتطلب طلب HTTPS إلى Google ReCaptcha قبل حساب الاستجابة.
 +
 
 +
فيما يلي بعض الأفكار حول كيفية إخفاء حقول honeypot بواسطة JavaScript و / أو CSS:
 +
* ضع الحقول خارج المنطقة المرئية من الصفحة.
 +
* جعل العناصر صغيرة جدًا أو تلوينها بنفس خلفية الصفحة.
 +
* اترك الحقول معروضة، ولكن أخبر البشر بتركها فارغة.
 +
يعتبر اختبار CAPTCHA السلبي الأكثر بساطة هو حقل honeypot مخفي واحد. على جانب الخادم، ستتحقق من قيمة الحقل: إذا كان يحتوي على أي نص، فيجب أن يكون عبارة عن برنامج تتبع. بعد ذلك، يمكنك إما تجاهل المشاركة أو إظهار نتيجة إيجابية، ولكن لا يمكنك حفظ المشاركة في قاعدة البيانات. بهذه الطريقة سوف يكون bot راضيًا ويتحرك.
 +
 
 +
يمكنك العثور على اختبارات CAPTCHA سلبية أكثر تعقيدًا في مشاركة مدونة Ned Batchelder:
 +
* تضمين حقل مع الطابع الزمني UTC الحالي فيه والتحقق من ذلك على الخادم. إذا كان بعيدًا جدًا في الماضي، أو إذا كان في المستقبل، فإن النموذج غير صالح.
 +
* عشوائية أسماء الحقول.
 +
* ضمن أكثر من حقل honeypot من جميع الأنواع، بما في ذلك أزرار الإرسال.
 +
لاحظ أن هذا لا يحميك إلا من البوتات التلقائية، ولا يمكن إيقاف برامج التتبع المستهدفة المخصصة لذلك. لذلك قد لا تكون اختبارات CAPTCHA السلبية جيدة لحماية نماذج تسجيل الدخول.
 +
 
 +
=== التسجيل ===
 +
أخبر Rails بعدم وضع كلمات المرور في ملفات السجل.
 +
 
 +
بشكل افتراضي، تسجل Rails جميع الطلبات التي أجريت على تطبيق الويب. ولكن ملفات السجل يمكن أن تكون مشكلة أمنية كبيرة، لأنها قد تحتوي على بيانات اعتماد تسجيل الدخول وأرقام بطاقات الائتمان وما إلى ذلك. عند تصميم مفهوم أمان تطبيق ويب، يجب أن تفكر أيضًا في ما سيحدث إذا حصل أحد المهاجمين على (الوصول الكامل) إلى خادم الويب. سيكون تشفير الأسرار وكلمات المرور في قاعدة البيانات غير ذي جدوى، إذا كانت ملفات السجل تسردها بنص واضح. يمكنك تصفية معاملات طلب معينة من ملفات السجل الخاصة بك عن طريق إلحاقها بـ config.filter_parameters في تكوين التطبيق. توضع علامة على هذه المعاملات
 +
 
 +
[FILTERED] في السجل.
 +
 
 +
config.filter_parameters << :password
 +
 
 +
ملاحظة: ترشح المعاملات المقدمة بواسطة التعبير العادي المطابق الجزئي. يضيف Rails الافتراضي: كلمة المرور في المهيأ المناسب (initializers / filter_parameter_logging.rb) وتهتم بمعاملات كلمة المرور النموذجية وكلمة password_confirmation.
 +
 
 +
=== كلمات المرور الجيدة ===
 +
ملاحظة: هل تجد صعوبة في تذكر كل كلمات المرور الخاصة بك؟ لا تدونها، ولكن استخدم الحروف الأولية لكل كلمة في جملة سهلة التذكر.
 +
 
 +
قام بروس شناير، وهو تقني أمني، بتحليل 34000 اسم مستخدم وكلمة مرور في العالم الحقيقي من هجوم MySpace للتصيد الاحتيالي المذكور أدناه. اتضح أن معظم كلمات المرور من السهل جدًا اختراقها. كلمات المرور العشرين الأكثر شيوعًا هي:
 +
 
 +
password1, abc123, myspace1, password, blink182, qwerty1, ****you, 123abc, baseball1, football1, 123456, soccer, monkey1, liverpool1, princess1, jordan23, slipknot1, superman1, iloveyou1, and monkey.
 +
 
 +
من المثير للاهتمام أن 4٪ فقط من كلمات المرور هذه كانت كلمات معجم وأن الأغلبية العظمى هي أبجدية رقمية. ومع ذلك، تحتوي يستخدم روبي نهجًا مختلفًا بعض الشيء عن العديد من اللغات الأخرى لتتطابق مع نهاية وبداية السلسلة. هذا هو السبب في أن العديد من كتب روبي ورييلز يخطئون. إذن كيف يكون هذا تهديدًا أمنيًا؟ لنفترض أنك تريد التحقق من صحة حقل عنوان URL بشكل غير صحيح وأنك استخدمت تعبيرًا عاديًا بسيطًا كالتالي:قواميس تكرارات كلمة المرور على عدد كبير من كلمات المرور اليوم، وتجربة جميع أنواع تركيبات (أبجدية). إذا كان المهاجم يعرف اسم المستخدم الخاص بك وكنت تستخدم كلمة مرور ضعيفة، سيخترق حسابك بسهولة.
 +
 
 +
كلمة المرور الجيدة هي تركيبة أبجدية رقمية طويلة من الحالات المختلطة. بما أنه من الصعب تذكر ذلك، فمن المستحسن أن ندخل فقط الأحرف الأولى من الجملة التي يمكنك تذكرها بسهولة. على سبيل المثال "The quick brown fox jumps over the lazy dog" سيكون "Tqbfjotld". لاحظ أن هذا مجرد مثال، يجب ألا تستخدم عبارات معروفة مثل هذه، كما قد تظهر في قواميس التكسير، أيضًا.
 +
 
 +
=== التعبيرات العادية ===
 +
ملاحظة: من الوقائع الشائعة في تعبيرات Ruby العادية هي مطابقة بداية السلسلة ونهايتها بـ ^ و $ ، بدلاً من \ A و \ z.
 +
 
 +
يستخدم روبي نهجًا مختلفًا بعض الشيء عن العديد من اللغات الأخرى لتتطابق مع نهاية وبداية السلسلة. هذا هو السبب في أن العديد من كتب Ruby و Rails يخطئون. إذن كيف يكون هذا تهديدًا أمنيًا؟ لنفترض أنك تريد التحقق من صحة حقل عنوان URL بشكل غير صحيح وأنك استخدمت تعبيرًا عاديًا بسيطًا كالتالي:
 +
 
 +
/^https?:\/\/[^\n]+$/i
 +
 
 +
هذا قد يعمل بشكل جيد في بعض اللغات. ومع ذلك، في روبي ^ و $ يطابق خط البداية ونهاية الخط. وبالتالي فإن عنوان URL مثل هذا يمرر الفلتر بدون مشاكل:
 +
 
 +
javascript:exploit_code();/*
 +
 
 +
<nowiki>http://hi.com</nowiki>
 +
 
 +
<nowiki>*</nowiki>/
 +
 
 +
يجتاز عنوان URL هذا الفلتر؛ لأن التعبير العادي يطابق - السطر الثاني، لا يهم البقية. الآن تخيل أنه لدينا عرضًا أظهر عنوان URL مثل هذا:
 +
 
 +
link_to "Homepage", @user.homepage
 +
 
 +
يبدو الارتباط بريئًا للزائرين، ولكن عند النقر عليه، ينفذ وظيفة JavaScript "exploit_code" أو أي JavaScript آخر يوفره المهاجم.
 +
 
 +
لإصلاح التعبير العادي، يجب استخدام \ A و \ z بدلاً من ^ و $، مثل:
 +
 
 +
/\Ahttps?:\/\/[^\n]+\z/i
 +
 
 +
بما أن هذا خطأ متكرر، فإن مدقق الصيغة (validates_format_of) يطرح الآن استثناء إذا كان التعبير العادي المقدم يبدأ بـ ^ أو ينتهي بـ $. إذا كنت بحاجة إلى استخدام ^ و $ بدلاً من \ A و \ z (وهو أمر نادر الحدوث)، فيمكنك تعيين: خيار متعدد الأسطر إلى true، مثل:
 +
 
 +
<nowiki>#</nowiki> content should include a line "Meanwhile" anywhere in the string
 +
 
 +
validates :content, format: { with: /^Meanwhile$/, multiline: true }
 +
 
 +
لاحظ أن هذا لا يحميك إلا من الخطأ الأكثر شيوعًا عند استخدام أداة التحقق من الصيغة - عليك دائمًا أن تضع في اعتبارك أن ^ و $ يتطابقان مع بداية السطر ونهاية السطر في Ruby، وليس بداية ونهاية السلسلة.
 +
 
 +
=== تصعيد الصلاحيات ===
 +
ملاحظة: قد يؤدي تغيير معامل واحد إلى منح المستخدم وصولاً غير مصرح به. تذكر أنه قد يتغير كل معامل، بغض النظر عن مدى إخفاءه أو تشويشه.
 +
 
 +
المعامل الأكثر شيوعًا التي قد يعبث بها المستخدم هو معامل المعرّف، كما هو الحال في <nowiki>http://www.domain.com/project/1،</nowiki> في حين أن الرقم 1 هو المعرف. سوف تكون متاحة في params في وحدة تحكم. هناك، على الأرجح ستفعل شيئًا كالتالي:
 +
 
 +
@project = Project.find(params[:id])
 +
 
 +
هذا أمر لا بأس به بالنسبة لبعض تطبيقات الويب، ولكن بالتأكيد ليس إذا كان المستخدم غير مخول لعرض جميع المشاريع. إذا غيّر المستخدم المعرف إلى 42، ولا يُسمح له برؤية تلك المعلومات، فسيكون بإمكانه الوصول إليها على أي حال. بدلاً من ذلك، استفسر عن حقوق وصول المستخدم أيضًا:
 +
 
 +
@project = @current_user.projects.find(params[:id])
 +
 
 +
اعتمادًا على تطبيق الويب الخاص بك، سيكون هناك العديد من المعاملات التي يمكن للمستخدم التلاعب بها. كقاعدة عامة، لا توجد بيانات إدخال المستخدم آمنة، حتى يثبت العكس، ومن المحتمل أن يتعامل مع كل معامل من المستخدم.
 +
 
 +
لا تنخدع بالأمن عن طريق التعتيم وأمن JavaScript. تتيح لك أدوات المطوّرين مراجعة الحقول المخفية لكل نموذج وتغييرها. يمكن استخدام JavaScript للتحقق من صحة بيانات إدخال المستخدم، ولكن بالتأكيد لا يمنع المهاجمين من إرسال طلبات ضارة ذات قيم غير متوقعة. تسجل الوظيفة الإضافية Firebug لـ Mozilla Firefox كل طلب وقد تكررها وتغيرها. هذه طريقة سهلة لتجاوز أي عمليات التحقق من جافا سكريبت. وهناك أيضًا البروكسي من جانب العميل تسمح لك باعتراض أي طلب واستجابة من وإلى الإنترنت.
 +
 
 +
== الحقن ==
 +
ملاحظة: الحقن هو فئة من الهجمات التي تدخل رمز أو معاملات ضارة في تطبيق ويب من أجل تشغيله ضمن سياق الأمان الخاص به. الأمثلة البارزة للحقن هي البرمجة عبر المواقع (XSS) وحقن SQL.
 +
 
 +
الحقن صعب للغاية، لأن نفس الكود أو المعامل يمكن أن تكون خبيثة في سياق واحد، ولكنها غير ضارة تمامًا في سياق آخر. يمكن أن يكون السياق عبارة عن لغة برمجة نصية أو استعلام أو لغة برمجة أو shell أو طريقة Ruby / Rails. تغطي الأقسام التالية جميع السياقات المهمة التي قد تحدث فيها هجمات الحقن. القسم الأول، ومع ذلك، يغطي قرار معماري فيما يتعلق حقن.
 +
 
 +
=== القوائم البيضاء والقوائم السوداء ===
 +
ملاحظة: عند تطهير شيء ما أو حمايته أو التحقق منه، تفضل القوائم البيضاء فوق القوائم السوداء.
 +
 
 +
يمكن أن تكون القائمة السوداء قائمة بعناوين البريد الإلكتروني السيئة أو الإجراءات غير العامة أو علامات HTML غير الصحيحة. هذا يعارض القائمة البيضاء التي تسرد عناوين البريد الإلكتروني الجيدة، والإجراءات العامة، وعلامات HTML الجيدة وما إلى ذلك. على الرغم من أنه من غير الممكن في بعض الأحيان إنشاء قائمة بيضاء (في مرشح الرسائل الاقتحامية، على سبيل المثال)، تفضل استخدام طرق القائمة البيضاء:
 +
* استخدم before_action باستثناء: [...] بدلاً من فقط: [...] للإجراءات المتعلقة بالأمان. بهذه الطريقة لا تنس أن تقوم بتمكين التحقق من الأمان للإجراءات المضافة حديثًا.
 +
* اسمح باستخدام <nowiki><strong> بدلاً من إزالة <script> ضد البرمجة النصية عبر المواقع (XSS). انظر أدناه للحصول على التفاصيل.</nowiki>
 +
* لا تحاول تصحيح إدخال المستخدم بواسطة القوائم السوداء:
 +
 
 +
* هذا سيجعل الهجوم يعمل: ("","<sc<script>ript>".gsub("<script>"
 +
* لكن ارفض الإدخال غير الصحيح.
 +
القوائم البيضاء هي أيضاً مقاربة جيدة ضد العامل البشري في نسيان شيء ما في القائمة السوداء.
 +
 
 +
=== حقن SQL ===
 +
ملاحظة: وبفضل الأساليب الذكية، لا يعد ذلك مشكلة في معظم تطبيقات Rails. ومع ذلك، هذا هجوم مدمر وشائع في تطبيقات الويب، لذلك من المهم فهم المشكلة.
 +
 
 +
==== المقدمة ====
 +
تهدف هجمات حقن SQL إلى التأثير على استعلامات قاعدة البيانات عن طريق معالجة معاملات تطبيق الويب. الهدف الشائع من هجمات حقن SQL هو تجاوز التفويض. هدف آخر هو تنفيذ معالجة البيانات أو قراءة البيانات التعسفية. في ما يلي مثال على كيفية عدم استخدام بيانات إدخال المستخدم في استعلام:
 +
 
 +
Project.where("name = '#{params[:name]}'")
 +
 
 +
قد يكون هذا في إجراء بحث ويمكن للمستخدم إدخال اسم مشروع يريد العثور عليه. إذا قام مستخدم ضار بإدخال --OR 1' فإن استعلام SQL الناتج سيكون:
 +
 
 +
SELECT * FROM projects WHERE name = ' ' OR 1 --'
 +
 
 +
تبدأ الشرطتان تعليقًا يتجاهل كل شيء بعده. لذا يرجع الاستعلام كافة السجلات من جدول المشاريع بما في ذلك المحجوبة للمستخدم. وذلك لأن الشرط صحيح لجميع السجلات.
 +
 
 +
==== تجاوز التخويل ====
 +
عادة ما يتضمن تطبيق الويب التحكم في الوصول. يدخل المستخدم بيانات اعتماد تسجيل الدخول الخاصة بهم ويحاول تطبيق الويب العثور على السجل المطابق في جدول المستخدمين. يمنح التطبيق الوصول عندما يجد سجلاً. ومع ذلك، قد يتجاوز المهاجم هذا التحقق باستخدام إدخال SQL. يعرض المثال التالي استعلامًا نموذجيًا لقاعدة البيانات في Rails للعثور على السجل الأول في جدول المستخدمين الذي يطابق معاملات بيانات اعتماد تسجيل الدخول التي يوفرها المستخدم.
 +
 
 +
User.find_by("login = '#{params[:name]}' AND password = '#{params[:password]}'")
  
هناك العديد من الاحتمالات الأخرى، مثل استخدام علامة <script> لتقديم طلب عبر الموقع إلى عنوان URL باستخدام استجابة JSONP أو JavaScript. الاستجابة هي تعليمات برمجية قابلة للتنفيذ يمكن للمهاجم العثور على طريقة للتشغيل، ربما استخراج البيانات الحساسة. للحماية من تسرب البيانات هذا، يجب علينا منع علامات <script> عبر المواقع. ومع ذلك، فإن طلبات Ajax تلتزم بسياسة المتصفح نفسها (فقط يُسمح لموقعك ببدء XmlHttpRequest) حتى نتمكن من السماح لهم بإرجاع استجابات JavaScript بأمان.
+
إذا قام المهاجم بإدخال 'OR' 1 '=' 1 كاسم، و 'OR' 2 '>' 1 ككلمة المرور، فسيكون استعلام SQL الناتج:
  
ملاحظة: لا يمكننا تمييز أصل العلامة <script> — سواء كانت علامة على موقعك الخاص أو على موقع ضار آخر — لذا يجب علينا حظر جميع <script> عبر اللوحة، حتى إذا كان في الأصل أصلًا آمنًا النصي خدم من موقعك الخاص. في هذه الحالات، تخطي حماية CSRF بشكل صريح من الإجراءات التي تخدم جافا سكريبت الموجهة لعلامة <script>.
+
SELECT * FROM users WHERE login = <nowiki>''</nowiki> OR '1'='1' AND password = <nowiki>''</nowiki> OR '2'>'1' LIMIT 1
  
للحماية من جميع الطلبات المزورة الأخرى، نقدم رمز الأمان المطلوب الذي يعرفه موقعنا ولكن المواقع الأخرى لا تعرفه. نحن نُضمن رمز الأمان في الطلبات والتحقق من ذلك على الخادم. هذا هو واحد في وحدة تحكم التطبيق الخاص بك، وهو الافتراضي لتطبيقات ريلز التي أُنشئت حديثا:
+
سيجد هذا ببساطة السجل الأول في قاعدة البيانات، ويمنح الوصول إلى هذا المستخدم.
  
protect_from_forgery with: :exception
+
==== قراءة غير مصرح بها ====
 +
ربط العبارة UNION استعلامات SQL اثنين وإرجاع البيانات في مجموعة واحدة. يمكن للمهاجم استخدامه لقراءة البيانات التعسفية من قاعدة البيانات. لنأخذ المثال من الأعلى:
  
سيتضمن ذلك تلقائيًا رمزًا للأمان في جميع النماذج وطلبات Ajax التي أُنشئت بواسطة ريلز. إذا كان الرمز المميز للأمان لا يطابق ما كان متوقعًا، يطرح استثناء.
+
Project.where("name = '#{params[:name]}'")
  
ملاحظة: بشكل افتراضي، يتضمن ريلز محولًا للبرمجة غير مزعجة، يضيف رأسًا يسمى X-CSRF-Token مع رمز الأمان على كل مكالمة GET Ajax غير. بدون هذا العنوان، لن تقبل طلبات غير GET Ajax بواسطة ريلز. عند استخدام مكتبة أخرى لإجراء مكالمات Ajax، من الضروري إضافة رمز الأمان كعنوان افتراضي لمكالمات Ajax في مكتبتك. للحصول على الرمز، ألقِ نظرة على العلامة <meta name = 'csrf-token' content = 'THE-TOKEN'> المطبوعة بواسطة <٪ = csrf_meta_tags٪> في عرض التطبيق الخاص بك.
+
والآن دعونا نحقن استعلام آخر باستخدام بيان UNION:
  
من الشائع استخدام ملفات تعريف الارتباط الدائمة لتخزين معلومات المستخدم، مع ملفات تعريف الارتباط على سبيل المثال. في هذه الحالة، لن تمسح ملفات تعريف الارتباط ولن تكون حماية CSRF من الصندوق فعالة. إذا كنت تستخدم مخزن ملفات تعريف ارتباط مختلفًا عن الجلسة لهذه المعلومات، فيجب عليك التعامل مع ما تفعله بنفسك:
+
') UNION SELECT id,login AS name,password AS description,1,1,1 FROM users --
  
rescue_from ActionController::InvalidAuthenticityToken do |exception|
+
سيؤدي ذلك إلى استعلام SQL التالي:
  
 sign_out_user # Example method that will destroy the user cookies
+
SELECT * FROM projects WHERE (name = <nowiki>''</nowiki>) UNION
  
End
+
 SELECT id,login AS name,password AS description,1,1,1 FROM users --'
  
يمكن وضع التابع أعلاه في ApplicationController وسيستدعى عندما يكون رمز CSRF غير موجود أو غير صحيح على طلب غير GET.
+
لن تكون النتيجة قائمة مشاريع (لأنه لا يوجد مشروع باسم فارغ)، ولكن قائمة بأسماء المستخدمين وكلمات المرور الخاصة بهم. نأمل أن تكون كلمات المرور مشفرة في قاعدة البيانات! المشكلة الوحيدة للمهاجم هي أن عدد الأعمدة يجب أن يكون هو نفسه في كلا الاستعلامات. هذا هو السبب في أن الاستعلام الثاني يتضمن قائمة بالأسماء (1)، والتي ستكون دائمًا القيمة 1، لمطابقة عدد الأعمدة في طلب البحث الأول.
  
لاحظ أن الثغرات الأمنية في البرامج النصية للمواقع المشتركة (XSS) تتجاوز جميع إجراءات حماية CSRF. يتيح XSS للمهاجم الوصول إلى جميع العناصر على الصفحة، حتى يتمكن من قراءة رمز الأمان CSRF من نموذج أو إرسال النموذج مباشرةً. اقرأ المزيد عن XSS لاحقًا.
+
أيضاً، يعيد الاستعلام الثاني تسمية بعض الأعمدة باستخدام عبارة AS بحيث يعرض تطبيق الويب القيم من جدول المستخدم. تأكد من تحديث Rails الخاصة بك إلى 2.1.1 على الأقل.
  
== إعادة التوجيه والملفات ==
+
==== التدابير المضادة ====
هناك فئة أخرى من الثغرات الأمنية تحيط باستخدام إعادة التوجيه والملفات في تطبيقات الويب.
+
يحتوي Ruby on Rails على فلتر مدمج لأحرف SQL الخاصة، والتي ستفوق "،"، حرف NULL وفواصل الأسطر. استخدم  
  
=== إعادة التوجيه ===
+
(Model.find(id او (Model.find_by_some thing(something يطبق هذا الإجراء تلقائيًا. ولكن في تجزئة SQL، خاصة في شروط التجزئة (where("...")) أو توابع ()connection.execute أو ()Model.find_by_sql، يجب أن تطبق يدويًا.
ملاحظة: إعادة التوجيه في تطبيق الويب هو أداة للتكسير أقل من قيمتها: لا يمكن للمهاجم توجيه المستخدم إلى موقع فخ فقط، بل قد يؤدي أيضًا إلى إنشاء هجوم قائم بذاته.
 
  
عندما يُسمح للمستخدم بتمرير (أجزاء) عنوان URL لإعادة التوجيه، فمن المحتمل أن يكون عرضة للخطر. قد يكون الهجوم الأكثر وضوحًا هو إعادة توجيه المستخدمين إلى تطبيق ويب مزيف يبدو تمامًا كالأصل الأصلي. هذا الهجوم المزيف يسمى التصيد الاحتيالي يعمل عن طريق إرسال رابط غير مريب في رسالة بريد إلكتروني إلى المستخدمين، عن طريق إدخال رابط XSS في تطبيق الويب أو وضع الرابط في موقع خارجي. إنه غير مثير للشك، لأن الرابط يبدأ بعنوان URL إلى تطبيق الويب ويخفي عنوان URL للموقع الخبيث في معامل إعادة التوجيه: <nowiki>http://www.example.com/site/redirect؟to=www.attacker.com</nowiki> . في ما يلي مثال على إجراء قديم:
+
بدلاً من تمرير سلسلة إلى خيار الشروط، يمكنك تمرير مصفوفة لتعقيم السلاسل الملوثة مثل:
  
def legacy
+
Model.where("login = ? AND password = ?", entered_user_name, entered_password).first
  
 redirect_to(params.update(action:'main'))
+
كما ترى، الجزء الأول من المصفوفة عبارة عن جزء SQL يحتوي على علامات استفهام. الإصدارات المعقمة للمتغيرات في الجزء الثاني من المصفوفة تحل محل علامات الاستفهام. أو يمكنك تمرير تجزئة لنفس النتيجة:
  
End
+
Model.where(login: entered_user_name, password: entered_password).first
  
سيؤدي هذا إلى إعادة توجيه المستخدم إلى الإجراء الرئيسي إذا حاول الوصول إلى إجراء قديم. كان الهدف هو الحفاظ على معاملات عنوان URL للإجراء القديم وتمريرها إلى الإجراء الرئيسي. ومع ذلك، يمكن استغلالها من قِبل المهاجم إذا تضمنت مفتاح مضيف في عنوان URL:
+
نموذج المصفوفة أو التجزئة متاح فقط في الحالات النموذجية. يمكنك محاولة() sanitize_sql في مكان آخر. اجعلها عادة التفكير في العواقب الأمنية عند استخدام سلسلة خارجية في SQL.
  
<nowiki>http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com</nowiki>
+
=== البرمجة عبر المواقع (XSS) ===
 +
ملاحظة: الأكثر انتشارًا، وأحد أكثر نقاط الضعف الأمنية تدميراً في تطبيقات الويب هو XSS. هذا الهجوم الخبيث يضخ رمزًا تنفيذيًا من جانب العميل. يوفر Rails طرق المساعد لإيقاف هذه الهجمات.
  
إذا كان في النهاية عنوان URL، فلن يكون من الممكن ملاحظته ويعيد توجيه المستخدم إلى مضيف attacker.com. سيكون الإجراء المضاد البسيط هو تضمين المعاملات المتوقعة فقط في الإجراء القديم (مرة أخرى نهج القائمة البيضاء، بدلاً من إزالة المعاملات غير المتوقعة). وإذا أعدت التوجيه إلى عنوان URL، فتحقق من ذلك باستخدام قائمة بيضاء أو تعبير عادي.
+
==== نقاط الدخول ====
 +
نقطة الإدخال هي عنوان URL ضعيف ومعاملاته حيث يمكن للمهاجم بدء هجوم.
  
==== Self-contained XSS ====
+
ونقاط الدخول الأكثر شيوعًا هي منشورات الرسائل وتعليقات المستخدمين وكتب الزائرين، ولكن عناوين المشروعات وأسماء المستندات وصفحات نتائج البحث كانت أيضًا عرضة - في كل مكان حيث يمكن للمستخدم إدخال البيانات. ولكن لا يجب بالضرورة أن تأتي المدخلات من مربعات الإدخال على مواقع الويب، يمكن أن تكون في أي معامل URL - واضحة أو مخفية أو داخلية. تذكر أن المستخدم قد اعترض أي حركة المرور. تجعل التطبيقات أو وكلاء موقع العميل من السهل تغيير الطلبات. هناك أيضا ناقلات هجوم أخرى مثل إعلانات لافتة.
هناك عملية إعادة توجيه أخرى تعتمد على XSS وتعمل في Firefox و Opera باستخدام بروتوكول البيانات. يعرض هذا البروتوكول محتوياته مباشرة في المستعرض ويمكن أن يكون أي شيء من HTML أو JavaScript إلى صور بأكملها:
 
  
data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K
+
يهاجم XSS العمل مثل هذا: يحقن أحد المهاجمين بعض الرموز، ويحفظه تطبيق الويب ويعرضه على صفحة، يُقدم لاحقًا إلى أحد الضحايا. تعرض معظم أمثلة XSS ببساطة صندوق تنبيه، لكنها أقوى من ذلك. يمكن لـ XSS سرقة ملف تعريف الارتباط، أو خطف الجلسة، أو إعادة توجيه الضحية إلى موقع ويب مزيف، أو عرض إعلانات لصالح المهاجم، أو تغيير العناصر على موقع الويب للحصول على معلومات سرية أو تثبيت برامج ضارة من خلال ثغرات أمنية في متصفح الويب.
  
هذا المثال عبارة عن JavaScript ترميز Base64 يعرض مربع رسالة بسيط. في عنوان URL لإعادة التوجيه، يمكن للمهاجم إعادة التوجيه إلى عنوان URL هذا باستخدام التعليمة البرمجية الضارة فيه. كإجراء مضاد، لا تسمح للمستخدم بتزويد (أجزاء) عنوان URL المراد إعادة توجيهه إليه.
+
خلال النصف الثاني من عام 2007، سجلت 88 نقطة ضعف في متصفحات موزيلا، 22 في سفاري، 18 في IE، و 12 في الأوبرا. كما وثق تقرير التهديدات العالمية لأمن الإنترنت من سيمانتك 239 نقطة ضعف في المتصفح في الأشهر الستة الأخيرة من عام 2007. ويعد Mpack إطارًا نشطًا وحديثًا للهجوم يستغل هذه الثغرات الأمنية. بالنسبة للمتسللين الإجراميين، فإنه من الأمور الجذابة للغاية استغلال ثغرة SQL-Injection في إطار تطبيق ويب وإدراج شفرة خبيثة في كل عمود جدول نصي. في أبريل / نيسان 200 ، اخترق أكثر من 510،000 موقع من هذا النوع، من بينها الحكومة البريطانية والأمم المتحدة والعديد من الأهداف البارزة.

مراجعة 17:19، 6 مارس 2019

تأمين تطبيقات ريلز

يصف هذا الدليل مشاكل الأمان الشائعة في تطبيقات الويب وكيفية تجنبها باستخدام ريلز. بعد قراءة هذا الدليل، ستتلعم:

  • جميع التدابير المضادة التي سيسلط الضوء عليها.
  • مفهوم الجلسات (sessions) في ريلز، و ما يُنفذ في وجود وسائل الهجوم المعروفة.
  • كيف يمكن أن يكون مجرد زيارة أحد المواقع مشكلة أمنية (مع CSRF).
  • ما عليك الانتباه عند العمل مع الملفات أو توفير واجهة إدارة.
  • كيفية إدارة المستخدمين: تسجيل الدخول والخروج وهجمات الطرق على جميع الطبقات.
  • أكثر الطرق المعروفة لهجوم الحقن.

المقدمة

تعمل إطارات تطبيقات الويب لمساعدة المطورين على بناء تطبيقات الويب. كما يساعد بعضها أيضًا في تأمين تطبيق الويب. في الواقع، لا يكون إطار واحد أكثر أمانًا من الآخر: إذا كنت تستخدمه بشكل صحيح، فستتمكن من إنشاء تطبيقات آمنة مع العديد من الأطر. لدى ريلز بعض التوابع المساعدة الذكية، على سبيل المثال ضد حقن SQL، بحيث لا يعد هذا مشكلة.

بشكل عام لا يوجد شيء مثل مكونات الأمن سهلة الإستخدام. يعتمد الأمن على الأشخاص الذين يستخدمون الإطار، وأحيانًا على طريقة التطوير. ويعتمد ذلك على جميع طبقات بيئة تطبيقات الويب: التخزين الخلفي (back-end storage) وخادم الويب وتطبيق الويب نفسه (وربما طبقات أو تطبيقات أخرى).

ومع ذلك، تقدر مجموعة غارتنر (Gartner Group) أن 75٪ من الهجمات موجودة على طبقة تطبيقات الويب، ووجدت أن "من بين 300 موقع مدقق، 97٪ منهم عرضة للهجوم". وذلك لأن من السهل نسبيًا استخدام تطبيقات الويب، حيث يسهل فهمها والتعامل معها، حتى من قبل الشخص العادي.

تتضمن التهديدات ضد تطبيقات الويب سرقة حساب المستخدم ، أو تجاوز التحكم في الوصول، أو قراءة أو تعديل البيانات الحساسة، أو عرض محتوى احتيالي. أو قد يتمكن أحد المهاجمين من تثبيت برنامج حصان طروادة (Trojan horse program) أو برنامج إرسال بريد إلكتروني غير مرغوب فيه، ويهدف إلى الإثراء المالي أو التسبب في تلف اسم العلامة التجارية عن طريق تعديل موارد الشركة. من أجل منع الهجمات وتقليل تأثيرها وإزالة نقاط الهجوم، عليك أولاً وقبل كل شيء أن تفهم تماما أساليب الهجوم من أجل إيجاد الإجراءات المضادة الصحيحة. هذا ما يهدف إليه هذا الدليل.

من أجل تطوير تطبيقات الويب الآمنة، يجب عليك مواكبة جميع الطبقات ومعرفة أعدائك. لمواكبة الاشتراك في قوائم بريدية أمنية، اقرأ مدونات الأمان وأجري عمليات الفحص والتحديثات الأمنية بشكل دوري (راجع فصل "الموارد الإضافية" في الأسفل). يُعمل ذلك يدويا لأن هذا هو كيف تجد مشاكل أمنية منطقية سيئة.

الجلسات

المكان لجيد لبدء البحث عن الأمان هو الجلسات، والتي يمكن أن تكون عرضةً لهجمات معينة.

ما هي الجلسات؟

ملاحظة: البروتوكول HTTP هو بروتوكول عديم الحالة. الجلسات تجعله ذي حالة (stateful).

تحتاج معظم التطبيقات إلى تتبع حالة معينة لمستخدم معين. قد تكون هذه محتويات سلة التسوق أو معرف المستخدم للمستخدم الذي قام بتسجيل الدخول حاليًا. بدون فكرة الجلسات، يجب على المستخدم تحديد وربما الاستيثاق على كل طلب. ستنشئ ريلز جلسة جديدة تلقائيًا إذا قام مستخدم جديد بالوصول إلى التطبيق. وستحمل جلسة موجودة إذا كان المستخدم قد استخدم التطبيق بالفعل.

عادةً ما تتكون الجلسة من جدول Hash من القيم ومعرف الجلسة، ,عادة ما تتكون من سلسلة 32 حرف، لتحديد ذلك الجدول. يتضمن كل ملف تعريف ارتباط (cookie) يُرسَل إلى متصفح العميل معرف الجلسة. وفي الاتجاه الآخر: يرسل المتصفح إلى الخادم كل طلب من العميل. في ريلز، يمكنك حفظ واسترجاع القيم باستخدام التابع session:

session[:user_id] = @current_user.id
User.find(session[:user_id])

معرف الجلسة

ملاحظة: معرف جلسة العمل عبارة عن سلسلة ست عشرية عشوائية تتكون من 32 محرف.

تُنشأ معرّف جلسة العمل باستخدام SecureRandom.hex الذي ينشئ سلسلة ست عشرية عشوائية باستخدام توابع خاصة بالمنصة (مثل OpenSSL أو ‎/dev/urandom أو Win32 CryptoAPI) لإنشاء أرقام عشوائية آمنة مشفرة. في الوقت الحالي ليس من الممكن إجهاض المعرفات الخاصة بجلسات ريلز.

اختطاف الجلسة

تحذير: يتيح سرقة معرف جلسة المستخدم لمهاجم استخدام تطبيق الويب باسم الضحية.

تحتوي العديد من تطبيقات الويب على نظام الاستيثاق: يوفر المستخدم اسم مستخدم وكلمة مرور، ويفحصهما تطبيق الويب ثم يخزن معرف المستخدم المقابل في جدول Hash للجلسة. من الآن فصاعدا، الجلسة صالحة. في كل طلب، سيحمل التطبيق المستخدم المحدد بواسطة معرف المستخدم في الجلسة، دون الحاجة إلى استيثاق جديد. يحدد معرف الجلسة في ملف تعريف الارتباط جلسة العمل.

بعد ذلك، فإن ملف تعريف الارتباط بمثابة استيثاق مؤقت لتطبيق الويب. أي شخص يستغل ملف تعريف ارتباط من شخص آخر قد يستخدم تطبيق الويب باسم هذا المستخدم - مع احتمال حدوث عواقب وخيمة. في ما يلي بعض الطرق لاختطاف جلسة، وإجراءاتها المضادة:

  • تحسس ملف تعريف الارتباط (cookie) في شبكة غير آمنة. يمكن أن تكون الشبكة المحلية اللاسلكية مثالًا على مثل هذه الشبكة. في شبكة LAN لاسلكية غير مشفرة، من السهل جدًا الاستماع إلى حركة مرور جميع العملاء المتصلين. بالنسبة إلى أداة إنشاء تطبيقات الويب ، فهذا يعني توفير اتصال آمن عبر طبقة المقابس الآمنة. في ريلز 3.1 والإصدارات الأحدث، تحقق ذلك عن طريق فرض اتصال SSL دائمًا في ملف تهيئة التطبيق الخاص بك:
config.force_ssl = true
  • معظم الناس لا يمسحون ملفات تعريف الارتباط بعد العمل في أماكن عامة (مثل مقاهي الإنترنت). لذلك، إذا لم يسجل المستخدم الأخير الخروج من تطبيق ويب، فسيتمكن غيره من استخدامه باسم هذا المستخدم. قدم للمستخدم زر تسجيل الخروج في تطبيق الويب، واجعله بارزًا.
  • تهدف العديد من عمليات استغلال البرامج النصية عبر المواقع (XSS) إلى الحصول على ملف تعريف الارتباط الخاص بالمستخدم. ستقرأ المزيد عن XSS لاحقًا.
  • بدلاً من سرقة ملف تعريف ارتباط غير معروف للمهاجم، يجري إصلاح مُعرِّف جلسة المستخدم (في ملف تعريف الارتباط) المعروف لهم. اقرأ المزيد حول ما يسمى بتثبيت الجلسة لاحقًا.

الهدف الرئيسي لمعظم المهاجمين هو كسب المال. تتراوح الأسعار السرية لحسابات تسجيل الدخول المسروقة للبنوك من 10 إلى 1000 دولار (اعتمادًا على المبلغ المتاح للأموال)، و 0.40 إلى 20 دولارًا لأرقام بطاقات الائتمان، و 1 إلى 8 دولارات لحسابات مواقع المزادات على الإنترنت، و 4 - 30 دولارًا لكلمات مرور البريد الإلكتروني، وفقًا لتقرير تهديد أمن الإنترنت العالمي من سيمانتك.

إرشادات الجلسة

فيما يلي بعض الإرشادات العامة حول الجلسات.

  • لا تخزن أشياءً كبيرةً في جلسة واحدة. بدلًا من ذلك، يجب تخزينها في قاعدة البيانات وحفظ معرّفها في الجلسة. سيؤدي ذلك إلى التخلص من صداع التزامن ولن يملأ مساحة التخزين الخاصة بالجلسة (حسب سعة التخزين التي اخترتها، انظر أدناه). ستكون هذه فكرة جيدة أيضًا، إذا قمت بتعديل بنية كائن وما زالت الإصدارات القديمة منه موجودةً في ملفات تعريف الارتباط الخاصة بمستخدم ما. من خلال تخزين جلسات من جانب الخادم، يمكنك مسح الجلسات، ولكن مع التخزين من جانب العميل، يكون من الصعب التخفيف من ذلك.
  • يجب عدم تخزين البيانات المهمة في الجلسة. إذا مسح المستخدم ملفات تعريف الارتباط الخاصة به أو أغلق المتصفح، فستُفقَد البيانات. أضف إلى ذلك أنَّه باستخدام وحدة التخزين على جانب العميل، يمكن للمستخدم قراءة البيانات.

تخزين الجلسة المشفرة

ملاحظة: يوفر ريلز العديد من آليات التخزين لجداول Hash لجلسة العمل. الأكثر أهمية هو ActionDispatch::Session::CookieStor.

يحفظ CookieStore جدول Hash للجلسة مباشرة في ملف تعريف الارتباط من جانب العميل. يسترد الخادم الجدول Hash لجلسة العمل من ملف تعريف الارتباط ويلغي الحاجة إلى معرِّف جلسة العمل. سيزيد ذلك من سرعة التطبيق بشكل كبير، لكنه خيار تخزين مثير للجدل وعليك التفكير في الآثار الأمنية وقيود التخزين الخاصة به:

  • تتطلب ملفات تعريف الارتباط حدًا صارمًا للحجم يبلغ 4 كيلوبايت. هذا جيد، حيث لا يجب تخزين كميات كبيرة من البيانات في الجلسة على أي حال، كما هو موضح سابقًا. تخزين معرف قاعدة بيانات المستخدم الحالي في جلسة هو ممارسة شائعة.
  • ملفات تعريف الارتباط الخاصة بالجلسات لا تنهي صلاحيتها بنفسها وقد يعاد استخدامها بشكل ضار. قد يكون من الجيد أن يؤدي تطبيقك إلى إبطال ملفات تعريف ارتباط الجلسة القديمة باستخدام طابع زمني مخزن.

يستخدم CookieStore مخزن ملف تعريف الارتباط المشفر (encrypted cookie jar) لتوفير موقع آمن ومشفر لتخزين بيانات الجلسات. وبالتالي، توفر الجلسات المستندة إلى ملفات تعريف الارتباط كلًّا من الأمان والسرية لمحتوياتها. يُشتق مفتاح التشفير، بالإضافة إلى مفتاح التحقق المستخدم لملفات تعريف الارتباط الموقعة، من قيمة الضبط secret_key_base.

بدءًا من الإصدار 5.2 من ريلز، تحمى ملفات تعريف الارتباط والجلسات المشفرة باستخدام تشفير AES GCM. هذا النوع من التشفير هو نوع من التشفير والاستيثاق الزوجي والتشفير في خطوة واحدة في حين تنتج أيضا نصوصًا أقصر مقارنة مع الخوارزميات الأخرى المستخدمة سابقا. يُشتق مفتاح ملفات تعريف الارتباط المشفرة مع AES GCM باستخدام قيمة زائدة محددة بواسطة القيمة config.action_dispatch.authenticated_encrypted_cookie_salt.

قبل هذا الإصدار، تُأمَّن ملفات تعريف الارتباط المشفرة باستخدام AES في الوضع CBC مع HMAC باستخدام SHA1 للاستيثاق. اشتقت مفاتيح هذا النوع من التشفير والتحقق من HMAC من خلال القيم الزائدة التي حددها config.action_dispatch.encrypted_cookie_salt و config.action_dispatch.encrypted_signed_cookie_salt على التوالي.

قبل الإصدار 4 من ريلز في كلا الإصدارين 2 و 3، كانت تُحمَى ملفات تعريف الارتباط الخاصة بالجلسات باستخدام التحقق من HMAC فقط. على هذا النحو، لم توفر ملفات تعريف الارتباط الخاصة بهذه الجلسة سوى سلامة المحتوى الخاص بها لأن بيانات الجلسة الفعلية خُزنت في نص عادي مشفر باعتباره base64. هذه هي الطريقة التي تعمل بها ملفات تعريف الارتباط في الإصدار الحالي من ريلز. لا تزال هذه الأنواع من ملفات تعريف الارتباط مفيدة لحماية سلامة بعض البيانات والمعلومات المخزنة من قبل العميل.

لا تستخدم كلمة سر تافهً لـ secret_key_base، أي كلمة من القاموس، أو ذات حروف أقل من 30 حرفًا! بدلًا من ذلك، استخدم rails secret لتوليد مفاتيح سرية!

من المهم أيضًا استخدام قيم زائدة مختلفة لملفات تعريف الارتباط المشفرة والموقعة. قد يؤدي استخدام نفس القيمة لقيم ضبط القيمة الزائدة (salt configuration values) المختلفة إلى نفس المفتاح المشتق المستخدم لميزات أمان مختلفة؛ وهذا قد يؤدي بدوره إلى إضعاف قوة المفتاح.

في تطبيقات الاختبار والتطوير، احصل على secret_key_base مشتق من اسم التطبيق. يجب أن تستخدم البيئات الأخرى مفتاحًا عشوائيًا موجودًا في config/credentials.yml.enc، كما هو موضح هنا في حالة فك تشفيرها:

secret_key_base: 492f...

إذا تلقيت طلبًا عرض فيه كلمة السر (على سبيل المثال أحد التطبيقات التي تمت مشاركة مصدرها)، ففكر بشدة في تغيير كلمة السر.

تدوير إعدادات ملفات تعريف الارتباط المشفرة والموقعة

يُعد التدوير (Rotation) مثاليًا لتغيير ضبط ملفات تعريف الارتباط وضمان عدم صلاحية ملفات تعريف الارتباط القديمة على الفور. عندئذٍ، ستتاح الفرصة للمستخدمين لديك لزيارة موقعك، وقراءة ملفات تعريف الارتباط الخاصة بهم مع تهيئة قديمة وإعادة كتابتها مع التغيير الجديد. يمكن بعد ذلك إزالة التدوير بعد أن تكون مطمئنًّا بما يكفي من امتلاك المستخدمين الفرصة لتحديث ملفات تعريف الارتباط الخاصة بهم.

من الممكن تدوير الأصفار والخدمات المستخدمة لملفات تعريف الارتباط المشفرة والموقعة.

على سبيل المثال، لتغيير القيمة المشفرة المختصرة (digest) المستخدمة لملفات تعريف الارتباط المشفرة الموقعة من SHA1 إلى SHA256، يجب أولًا تعيين قيمة الضبط الجديدة:

Rails.application.config.action_dispatch.signed_cookie_digest = "SHA256"

أضف الآن تدويرًا للقيمة المشفرة عبر SHA1 المختصرة القديمة بحيث تُحدث ملفات تعريف الارتباط الحالية بسلاسة إلى القيمة المشفرة عبر SHA256 المختصرة الجديدة.

Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
  cookies.rotate :signed, digest: "SHA1"
end

ثم ستُحسَب القيمة المشفرة المختصرة لأي ملفات تعريف الارتباط المكتوبة باستخدام SHA256. لا يزال من الممكن قراءة ملفات تعريف الارتباط القديمة التي كُتبت باستخدام SHA1، وإذا جرى الوصول إليها آنذاك، سيعاد كتابتها مع القيمة المشفرة المختصرة الجديد بحيث يجري ترقيتها ولن تكون غير صالحة عند إزالة التدوير.

وبمجرد أن لم يعد لدى المستخدمين الذين يملكون ملفات تعريف الارتباط الموقعة ذات القيمة المختصرة والمشفرة عبر SHA1 فرصةً لإعادة كتابة ملفات تعريف الارتباط الخاصة بهم، أزل الدوران.

على الرغم من أنه يمكنك إعداد العديد من عمليات التدوير على الوجه الذي تريد، فمن غير المعتاد إجراء العديد من التدويرات في وقت واحد.

لمزيد من التفاصيل حول تدوير المفاتيح مع الرسائل المشفرة والموقعة بالإضافة إلى الخيارات المختلفة التي يقبلها التابع rotate، يرجى الرجوع إلى توثيق واجهة برمجة تطبيقات MessageEncryptor و MessageVerifier.

هجمات الإعادة على جلسات CookieStore

ملاحظة: نوع آخر من الهجوم عليك أن تكون على دراية به عند استخدام CookieStore هو هجوم الإعادة (replay attack).

تُنفَّذ هذه الهجمات بالشكل التالي:

  • يتلقى المستخدم كمية مبلغ المال، ثم يخزن المبلغ في جلسة (وهي فكرة سيئة على أي حال، لكننا سنفعل ذلك لأغراض العرض التوضيحي).
  • يشتري المستخدم شيئًا.
  • تخزين قيمة المبلغ المعدلة الجديدة في الجلسة.
  • يأخذ المستخدم ملف تعريف الارتباط من الخطوة الأولى (الذي نسخوه مسبقًا) ويستبدل ملف تعريف الارتباط الحالي في المتصفح.
  • يمتلك المستخدم رصيده الأصلي مرة أخرى.

تضمين رقم خاص (nonce، وهو قيمة عشوائية) في الجلسة يقي من هجمات الإعادة. يكون الرقم الخاص صالحًا مرة واحدة فقط، ويتعين على الخادم تتبع جميع الأرقام الخاصة الصالحة. يصبح الأمر أكثر تعقيدًا إذا كان لديك عدة خوادم للتطبيق. من شأن تخزين الأرقام الخاصة في جدول قاعدة بيانات أن يهزم الهدف الكامل لـ CookieStore (تجنب الوصول إلى قاعدة البيانات).

أفضل حل لذلك هو عدم تخزين هذا النوع من البيانات في الجلسة، ولكن في قاعدة البيانات. في هذه الحالة، خزن الرصيد في قاعدة البيانات و login_in_user_id في الجلسة.

تثبيت الجلسة

ملاحظة: بصرف النظر عن سرقة معرف جلسة المستخدم، قد يُصلِح المهاجم معرف جلسة يعرفه ويجبر الضحية على استعماله، وهذا ما يسمى "تثبيت الجلسة" (Session Fixation).

[[ملف:session_fixation_Rails.png|بديل=خطوات تثبيت جلسة ذات معرف معلوم من طرف المهاجم وتوضيح كيفية خداع المستخدم لاستعمال معرف الجلسة ذاك وإنجاز الاستيثاق للمهاجم.|تصغير|خطوات تثبيت جلسة ذات معرف معلوم من طرف المهاجم وتوضيح كيفية خداع المستخدم لاستعمال معرف الجلسة ذاك وإنجاز الاستيثاق للمهاجم.]]

يركز هذا الهجوم على إصلاح معرِّف جلسة المستخدم المعروف للمهاجم، وإجبار متصفح المستخدم على استخدام هذا المعرف. لذلك، ليس من الضروري أن يسرق المهاجم معرف الجلسة بعد ذلك. إليك كيف يعمل هذا الهجوم:

  • يُنشئ المهاجم معرف جلسة صالح: يُحمِّل صفحة تسجيل الدخول الخاصة بتطبيق الويب حيث يريد إصلاح جلسة العمل، ثم يأخذ معرف جلسة العمل الموجود في ملف تعريف الارتباط من الاستجابة (راجع الرقمين 1 و 2 في الصورة).
  • يحتفظ المهاجم بالجلسة عن طريق الوصول إلى تطبيق الويب بشكل دوري من أجل منع انتهاء صلاحية الجلسة وإبقائها على قيد الحياة.
  • يفرض المهاجم على متصفح المستخدم استخدام معرف جلسة العمل هذا (راجع رقم 3 في الصورة). نظرًا لأنه لا يجوز لك تغيير ملف تعريف ارتباط لنطاق آخر (بسبب نفس سياسة الأصل)، يجب على المهاجم تشغيل JavaScript من مجال تطبيق الويب المستهدف. ينفَّذ هذا الهجوم عبر حقن شيفرة JavaScript في التطبيق بواسطة XSS. إليك مثال على ذلك:
<script>document.cookie="_session_id=16d5b78abb28e3d6206b60f22a03c8d9";</script>

سنتطرق إلى الهجوم XSS والحقن في وقت لاحق.

  • يغري المهاجم الضحية إلى الصفحة المصابة بشيفرة JavaScript. من خلال عرض الصفحة، سيغير متصفح الضحية معرف الجلسة إلى معرف الجلسة الملغوم الذي يمثِّل الفخ.
  • لمَّا كان معرف الجلسة الملغوم الجديد غير مستخدم بعد، فسيطلب تطبيق الويب من المستخدم إجراء استيثاق.
  • من الآن فصاعدا، سيتشارك الضحية والمهاجم استخدام تطبيق الويب مع الجلسة نفسها، إذ أصبحت الجلسة صالحة ولم يلاحظ الضحية الهجوم الذي حصل.

تثبيت الجلسة - التدابير الوقائية

تنبيه: سطر واحد من التعليمات البرمجية سوف يحميك من هجوم تثبيت الجلسة.

إن الإجراء المضاد الأكثر فاعلية هو إصدار معرف جلسة عمل جديد وإعلان أن الرقم القديم غير صالح بعد تسجيل الدخول بنجاح. بهذه الطريقة، لا يمكن للمهاجم استخدام معرف جلسة العمل الثابتة. هذا هو مضاد جيد ضد اختطاف الجلسة أيضًا. فيما يلي كيفية إنشاء جلسة جديدة في ريلز:

reset_session

إذا كنت تستخدم الجوهرة Devise الشائعة لإدارة المستخدمين، فستنتهي الجلسات تلقائيًا عند تسجيل الدخول وتسجيل الخروج نيابة عنك. إذا قمت بالتدوير الخاص بك، تذكر أن تنهي صلاحية الجلسة بعد تسجيل الدخول (عند إنشاء الجلسة). سيؤدي هذا إلى إزالة القيم من الجلسة، وبالتالي يتعين عليك نقلها إلى الجلسة الجديدة.

ومن التدابير المضادة الأخرى حفظ الخصائص الخاصة بمستخدم محدد في الجلسة، والتحقق منها في كل مرة يأتي فيها طلب، ورفض الوصول إذا كانت المعلومات غير متطابقة. يمكن أن تكون هذه الخصائص هي عنوان IP البعيد أو وكيل المستخدم (اسم مستعرض ويب)، على الرغم من أن الأخير غير مرتبط بمستخدم محدَّد بشدة. عند حفظ عنوان IP، يجب أن تضع في حسبانك أن هناك مزودي خدمة إنترنت أو مؤسسات كبيرة تضع مستخدميها خلف الوكلاء (proxies). قد تتغير هذه الخصائص على مدار الجلسة، لذلك لن يتمكن هؤلاء المستخدمون من استخدام التطبيق الخاص بك، أو سيستخدموه ولكن بشكل محدود فقط.

انتهاء الجلسة

ملاحظة: توسع الجلسات التي لا تنتهي صلاحيتها إطلاقًا الإطار الزمني لاحتمالية حدوث عدَّة هجمات مثل التزوير عبر الموقع (CSRF) واختطاف الجلسة وتثبيت الجلسة.

أحد الاحتمالات هو تعيين الطابع الزمني لإنتهاء صلاحية ملف تعريف الارتباط مع معرف جلسة العمل. ومع ذلك، يمكن للعميل تحرير ملفات تعريف الارتباط التي تخزن في متصفح الويب بحيث تصبح الجلسات المنتهية على الخادم أكثر أمانًا. فيما يلي مثال حول كيفية انهاء صلاحية الجلسات في جدول قاعدة البيانات. استدعي ("Session.sweep ("20 minutes لإنهاء الجلسات التي استُخدمت منذ أكثر من 20 دقيقة.

class Session < ApplicationRecord
  def self.sweep(time = 1.hour)
    if time.is_a?(String)
      time = time.split.inject { |count, unit| count.to_i.send(unit) }
    end
 
    delete_all "updated_at < '#{time.ago.to_s(:db)}'"
  end
end

قدم القسم السابق الذي يشرح "تثبيت الجلسة" مشكلة الحفاظ على الجلسات. يمكن للمهاجم الذي يحافظ على جلسة تنتهي كل خمس دقائق أن يبقى الجلسة حية إلى الأبد، على الرغم من أنك قد انتهيت من الجلسات. سيكون الحل البسيط لهذا هو إضافة العمود created_at إلى جدول الجلسات. الآن يمكنك حذف الجلسات التي أُنشئت منذ وقت طويل. استخدم هذا الخط في التابع sweep أعلاه:

delete_all "updated_at < '#{time.ago.to_s(:db)}' OR
  created_at < '#{2.days.ago.to_s(:db)}'"

تزوير الطلب عبر المواقع (CSRF)

تعمل طريقة الهجوم هذه على تضمين شفرة خبيثة أو ارتباط في صفحة تصل إلى تطبيق ويب يُعتقَد أن المستخدم قد أجرى استيثاقًا معه. إذا لم تنقضي مهلة جلسة تطبيق الويب، فقد ينفذ المهاجم أوامر غير مصرح بها.

[[ملف:csrf_refactoring.png|بديل=رسم توضيحي لهجمات تزوير الطلب عبر المواقع (CSRF).|تصغير|رسم توضيحي لهجمات تزوير الطلب عبر المواقع (CSRF).]]

في فصل الجلسات، تعلمت أن معظم تطبيقات ريلز تستخدم جلسات تستند إلى ملفات تعريف الارتباط. إما أن تخزن معرف جلسة العمل في ملف تعريف الارتباط وأن تحتوي على جدول Hash لجلسة من جانب الخادم، أو أن يكون الجدول Hash بأكلمه للجلسة على جانب العميل. في كلتا الحالتين، سيرسل المتصفح تلقائيًا ملف تعريف الارتباط على كل طلب إلى نطاق إذا تمكن من العثور على ملف تعريف ارتباط لهذا النطاق. تكمن النقطة المثيرة للجدل في أنه إذا جاء الطلب من موقع لنطاق مختلف، سيرسل أيضًا ملف تعريف الارتباط. لنبدأ بمثال:

  • يتصفح محمد لوحة الرسائل ويعرض مشاركة من أحد القراصنة (hacker) حيث يوجد عنصر صورة HTML مهيأ. يشير العنصر إلى أمر في تطبيق إدارة مشروع محمد، بدلًا من ملف الصورة نفسها:
    <img src="http://www.webapp.com/project/1/destroy">
    
  • لا تزال جلسة محمد على www.webapp.com على قيد الحياة، لأنه لم يقم بتسجيل الخروج قبل بضع دقائق.
  • من خلال عرض المشاركة، يجد المتصفح وسم الصورة. يحاول تحميل الصورة المشتبه بها من www.webapp.com. كما أوضحنا من قبل، يرسل أيضًا على طول ملف تعريف الارتباط بمعرف الجلسة الصحيح.
  • يتحقق تطبيق الويب على www.webapp.com من معلومات المستخدم في جدول Hash للجلسة المقابلة ويدمر المشروع بالمعرف 1. ثم يعيد صفحة نتائج غير متوقعة للذاكرة، لذا لن تُعرَض الصورة.
  • محمد لا يلاحظ الهجوم - ولكن يكتشف بعد بضعة أيام أن المشروع رقم واحد قد اختفى.

من المهم ملاحظة أن الصورة أو الوصلة الفعلية لا يجب وضعها بالضرورة في نطاق تطبيق الويب، يمكن أن تكون في أي مكان - في منتدى أو مشاركة مدونة أو بريد إلكتروني.

هجمات CSRF نادرةٌ جدًا في CVE (نقاط الضعف والمشاكل الشائعة)، إذ شكلت أقل من 0.1% من الهجمات في عام 2006، ولكنها في الحقيقة "عملاق نائم" (كما وصفها غروسمان[Grossman]). هذا في تناقض صارخ مع نتائج العديد من أعمال الاتفاقيات الأمنية، إذ تعد هجمات CSRF مشكلة أمنية خطيرة يجب الاهتمام بها.

إجراءات CSRF

ملاحظة: أولًا، كما هو مطلوب من قبل W3C، استخدم طلبيات GET و POST بشكل مناسب. ثانيًا، سيحمي رمز الأمان في طلبيات غير GET تطبيقك من هجمات CSRF.

يوفر بروتوكول HTTP أساسًا نوعين رئيسيين من الطلبات هما: GET و POST (يجب استخدام DELETE و PUT و PATCH مثل POST). يوفر World Wide Web Consortium) W3C) قائمة تحقق لاختيار GET أو POST:

استخدم GET إذا كان:

  • التفاعل أشبه بسؤال (بمعنى أنه عملية آمنة مثل الاستعلام أو قراءة العملية أو البحث).

استخدم POST إذا كان:

  • التفاعل أشبه بأمر، أو
  • التفاعل يغير حالة المورد بطريقة يتصورها المستخدم (على سبيل المثال، اشتراك في خدمة)، أو
  • المستخدم يُحمَّل مسؤولية نتائج التفاعل.

إذا كان تطبيق الويب الخاص بك هو RESTful، فقد يُستخدَم لأفعال HTTP إضافية، مثل PATCH أو PUT أو DELETE. ولكن، بعض متصفحات الويب القديمة لا تدعمها بل تدعم فقط GET و POST. يستخدم ريلز الحقل ‎_method المخفي لمعالجة هذه الحالات.

يمكن إرسال طلبات POST تلقائيًا أيضًا. في هذا المثال، يُظهَر الرابط www.harmless.com كوجهة في شريط الحالة للمتصفح. ولكنه في الواقع أنشأ بشكل ديناميكي نموذجًا جديدًا يرسل طلب POST.

<a href="http://www.harmless.com/" onclick="
  var f = document.createElement('form');
  f.style.display = 'none';
  this.parentNode.appendChild(f);
  f.method = 'POST';
  f.action = 'http://www.example.com/account/destroy';
  f.submit();
  return false;">To the harmless survey</a>

أو يضع المهاجم الرمز في معالج الحدث onmouseover الخاص بالصورة:

<img src="http://www.harmless.com/img" width="400" height="400" onmouseover="..." />

هناك العديد من الاحتمالات الأخرى، مثل استخدام الوسم <script> لتقديم طلب عبر الموقع إلى عنوان URL باستخدام استجابة JSONP أو JavaScript. الاستجابة هي تعليمات برمجية قابلة للتنفيذ يمكن للمهاجم العثور على طريقة لتنفيذها، وربما سرقة بيانات حساسة. للحماية من تسرب البيانات هذا، يجب علينا منع الوسم <script> عبر المواقع. ومع ذلك، فإن طلبات Ajax تلتزم بسياسة المتصفح نفسها (فقط يُسمح لموقعك ببدء XmlHttpRequest) حتى نتمكن من السماح لهم بإرجاع استجابات JavaScript بأمان.

ملاحظة: لا يمكننا تمييز أصل الوسم <script> — سواء كان وسمًا على موقعك الخاص أو على موقع ضار آخر — لذا يجب علينا حظر جميع الوسوم <script>، حتى إذا كانت في الأصل آمنةً مثلها مثل الوسوم المحملة من موقعك الخاص. في هذه الحالات، تخطي حماية CSRF بشكل صريح من الإجراءات التي تخدم JavaScript الموجهة للوسم <script>.

للحماية من جميع الطلبات المزورة الأخرى، نقدم رمز الأمان المطلوب الذي يعرفه موقعنا ولكن المواقع الأخرى لا تعرفه. نحن نُضمِّن رمز الأمان في الطلبات ونتحقق منه على الخادم. إليك أحد الأسطر في وحدة تحكم التطبيق الخاص بك، والذي يُضمَّن بشكل افتراضي في تطبيقات ريلز التي أُنشئَت حديثًا:

protect_from_forgery with: :exception

سيتضمن ذلك تلقائيًا رمزًا للأمان في جميع النماذج وطلبات Ajax التي أُنشئت بواسطة ريلز. إذا كان الرمز المميز للأمان لا يطابق ما كان متوقعًا، فسيرمى استثناء.

ملاحظة: بشكل افتراضي، يتضمن ريلز محولًا للشيفرات البرمجية غير المزعجة (unobtrusive scripting adapter)، الذي يضيف ترويسةً تدعى X-CSRF-Token مع رمز الأمان على كل استدعاء Ajax ليس GET. بدون هذه الترويسة، لن تقبل ريلز طلبات Ajax التي ليست GET. عند استخدام مكتبة أخرى لإجراء استدعاءات Ajax، من الضروري إضافة رمز الأمان كعنوان افتراضي لاستدعاءات Ajax في مكتبتك. للحصول على الرمز، ألقِ نظرة على الوسم ‎<meta name='csrf-token' content='THE-TOKEN'>‎ المطبوع بواسطة <‎%= csrf_meta_tags %‎> في عرض التطبيق الخاص بك.

من الشائع استخدام ملفات تعريف الارتباط الدائمة لتخزين معلومات المستخدم، مع cookies.permanent على سبيل المثال. في هذه الحالة، لن تًمسَح ملفات تعريف الارتباط ولن تكون الإجراءات المتبعة للحماية من هجمات CSRF فعالة. إذا كنت تستخدم مخزن ملفات تعريف ارتباط مختلفًا عن الجلسة لهذه المعلومات، فيجب عليك التعامل مع ما تفعله بنفسك:

rescue_from ActionController::InvalidAuthenticityToken do |exception|
  sign_out_user # Example method that will destroy the user cookies
end

يمكن وضع التابع أعلاه في ApplicationController وسيُستدعَى عندما يكون رمز CSRF غير موجود أو غير صحيح على طلب غير GET.

لاحظ أن ثغرات البرمجة عبر المواقع (XSS) تتجاوز جميع إجراءات الحماية من هجمات CSRF. يتيح XSS للمهاجم الوصول إلى جميع العناصر في الصفحة، حتى يتمكن من قراءة رمز الأمان CSRF من نموذج أو إرسال النموذج مباشرةً. سنتطرق إلى هجمات XSS لاحقًا.

إعادة التوجيه والملفات

هناك فئة أخرى من الثغرات الأمنية تحيط باستخدام إعادة التوجيه والملفات في تطبيقات الويب.

إعادة التوجيه

تحذير: إعادة التوجيه في تطبيق الويب هو أداة للتكسير ذات شأن بخس (underestimated cracker tool): لا يمكن للمهاجم توجيه المستخدم إلى موقع يحوي فخًا له فقط، بل قد يؤدي أيضًا إلى إنشاء هجوم قائم بذاته.

عندما يُسمَح للمستخدم بتمرير عنوان URL (أو جزءًا منه) لإعادة التوجيه، فمن المحتمل أن يكون عرضة للخطر. قد يكون الهجوم الأكثر وضوحًا هو إعادة توجيه المستخدمين إلى تطبيق ويب مزيف يبدو تمامًا كالتطبيق الأصلي. هذا الهجوم المزيف يسمى التصيد الاحتيالي (phishing attack) ويعمل عن طريق إرسال رابط غير مريب في رسالة بريد إلكتروني إلى المستخدمين عن طريق إدخال رابط XSS في تطبيق الويب أو وضع الرابط في موقع خارجي. إنه غير مثير للشك، لأنَّ الرابط يبدأ بعنوان URL إلى تطبيق الويب ويخفي عنوان URL للموقع الخبيث في معامل إعادة التوجيه مثل: http://www.example.com/site/redirect?to=www.attacker.com. في ما يلي مثال على إجراء قديم:

def legacy
  redirect_to(params.update(action:'main'))
end

سيؤدي هذا إلى إعادة توجيه المستخدم إلى الإجراء الرئيسي إذا حاول الوصول إلى إجراء قديم. كان الهدف هو الحفاظ على معاملات عنوان URL للإجراء القديم وتمريرها إلى الإجراء الرئيسي. ومع ذلك، يمكن استغلالها من قِبل المهاجم إذا تضمنت مفتاح مضيف في عنوان URL:

http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com

إذا كان في النهاية عنوان URL، فلن يكون من الممكن ملاحظته ويعيد توجيه المستخدم إلى مضيف attacker.com. سيكون الإجراء المضاد البسيط هو تضمين المعاملات المتوقعة فقط في الإجراء القديم (مرة أخرى نعود إلى أسلوب القائمة البيضاء، بدلًا من إزالة المعاملات غير المتوقعة). وإذا أعدت التوجيه إلى عنوان URL، فتحقق من ذلك باستخدام قائمة بيضاء أو تعبير عادي.

هجمات XSS القائمة بحد ذاتها

هناك عملية إعادة توجيه أخرى تعتمد على هجمات XSS وتعمل في Firefox و Opera باستخدام بروتوكول البيانات. يعرض هذا البروتوكول محتوياته مباشرة في المتصفح ويمكن أن يكون أي شيء من HTML أو JavaScript إلى صور بأكملها:

data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K

هذا المثال عبارة عن شيفرة JavaScript مشفرة عبر Base64 تعرض مربع رسالة بسيط. في عنوان URL لإعادة التوجيه، يمكن للمهاجم إعادة التوجيه إلى عنوان URL هذا باستخدام التعليمة البرمجية الضارة فيه. كإجراء مضاد، لا تسمح للمستخدم بتزويد عنوان URL (أو أجزاء منه) المراد إعادة توجيهه إليه.

تحميل الملفات

ملاحظة: تأكد من أن تحميلات ملف لا تستبدل ملفات أخرى مهمة، وعالج ملفات الوسائط (media files) بشكل غير متزامن.

تسمح العديد من تطبيقات الويب للمستخدمين بتحميل ملفات على الخادم. يجب دومًا ترشيح أسماء الملفات، التي قد يختارها المستخدم (جزئيًا)، حيث يمكن للمهاجم استخدام اسم ملف ضار للكتابة فوق أي ملف على الخادم. إذا خزنت الملفات المحملة في ‎/var/www/uploads، وقام المستخدم بإدخال اسم ملف مثل "‎../../../etc/passwd"، فقد يكتب فوق (يستبدل) ملف مهم. بالطبع، سيحتاج مترجم روبي إلى الأذونات المناسبة للقيام بذلك، وهو سبب آخر لتشغيل خوادم الويب و خوادم قواعد البيانات والبرامج الأخرى كمستخدم يونكس ذي صلاحيات أقل.

عند ترشيح أسماء ملفات التي يدخلها المستخدم، لا تحاول إزالة الأجزاء الضارة. فكر في موقف يزيل فيه تطبيق الويب كافة الأجزاء "‎../‎" في اسم الملف ويستخدم المهاجم سلسلة مثل "‎....//‎"، إذ ستكون النتيجة "‎../‎". من الأفضل استخدام أسلوب القائمة البيضاء الذي يتحقق من صحة اسم الملف مع مجموعة من المحارف المقبولة. هذا يعارض نهج القائمة السوداء الذي يحاول إزالة الأحرف غير المسموح بها. في حالة عدم وجود اسم ملف صالح، ارفضه (أو استبدل المحارف غير المقبولة)، ولكن لا تزله. إليك اسم الملف المطهَّر من الإضافة attachment_fu:

def sanitize_filename(filename)
  filename.strip.tap do |name|
    # بشكل صحيح مع مسارات ويندوز على لينكس File.basename ملاحظة: لا يعمل
    # لذا اجلب اسم الملف فقط دون كامل المسار
    name.sub! /\A.*(\\|\/)/, ''
    # أخيرًا، بدل شرطات سفلية مكان المحارف غير الأبجدية أو الرقمية أو  
    # الشرطات السفلية أو النقط 
    name.gsub! /[^\w\.\-]/, '_'
  end
end

هناك عيب كبير في المعالجة المتزامنة لعمليات تحميل الملفات (كما تفعل الإضافة attachment_fu مع الصور) هو ضعفه تجاه هجمات حجب الخدمة (denial-of-service attacks). يمكن للمهاجم بدء تحميل ملفات الصور بشكل متزامن من العديد من أجهزة الكمبيوتر مما يزيد من حمل الخادم وقد يؤدي إلى تعطيل الخادم أو إبطائه.

الحل الأفضل لذلك هو معالجة ملفات الوسائط بشكل غير متزامن: احفظ ملف الوسائط وجدول طلب معالجة في قاعدة البيانات. ستأتي بعدئذٍ عملية أخرى وتعالج الملف في الخلفية.

الشيفرات البرمجية القابلة للتنفيذ في الملفات المحملة

تحذير: قد تُنفَّذ شيفرة مصدرية في الملفات المحملة عند وضعها في مجلدات محددة. لا تضع الملفات المحملة في المجلد public/ لريلز إذا كان هو مجلد Apache الرئيسي.

يحتوي خادم الويب الشهير Apache على خيار يسمى DocumentRoot. هذا هو المجلد الرئيسي لموقع الويب، وسيُخدَّم كل شيء في شجرة هذا المجلد بواسطة خادم الويب. إذا كانت هناك ملفات ذات امتداد (لاحقة) معين، تُنفذ التعليمة البرمجية الموجودة بها عند الطلب (قد يتطلب ذلك تعيين بعض الخيارات). ومن أمثلة ذلك ملفات PHP و CGI. فكر الآن في موقف يُحمِّل فيه أحد المهاجمين ملفًا باسم "file.cgi" يحوي شيفرة فيه تُنفذ عندما يُنزِّل شخص ما الملف.

إذا كان الخيار DocumentRoot في خادم الويب Apache يشير إلى المجلد ‎/public لريلز، فلا تضع الملفات المحملة فيه، بل خزن الملفات في مستوى واحد لأعلى على الأقل.

تنزيل الملفات

ملاحظة: تأكد من عدم تمكن المستخدمين من تنزيل ملفات عشوائية.

مثلما يلزمك ترشيح أسماء الملفات المراد تحميلها، يجب عليك القيام بالأمر ذاته للملفات المراد تنزيلها. يرسل التابع ()send_file ملفات من الخادم إلى العميل. إذا كنت تستخدم اسم الملف الذي أدخله المستخدم، دون تصفية، فسيتمكن المستخدم من تنزيل أي ملف من خادمك:

send_file('/var/www/uploads/' + params[:filename])

ما عليك سوى تمرير اسم ملف مثل "‎../../../etc/passwd" لتنزيل معلومات تسجيل الدخول الخاصة بالخادم. حل هذه المشكلة بسيط وهو التحقق من أن الملف المطلوب موجود في المجلد المتوقع:

basename = File.expand_path('../../files', __dir__)
filename = File.expand_path(File.join(basename, @file.public_filename))
raise if basename !=
     File.expand_path(File.join(File.dirname(filename), '../../../'))
send_file filename, disposition: 'inline'

أسلوب آخر (إضافي) هو تخزين أسماء الملفات في قاعدة البيانات وتسمية الملفات الموجودة على القرص بعد المعرفات الموجودة في قاعدة البيانات. هذا أيضًا طريقة جيدة لتجنب تنفيذ شيفرة برمجية محتملة جرى تحميلها. تسلك الإضافة attachment_fu نفس السلوك أيضًا ولكن بطريقة مشابهة.

الإنترانت والأمان الإداري

واجهات إدارة إنترانت هي أهداف هجوم شائعة، لأنها تسمح بالوصول المميز. على الرغم من أن هذا سيتطلب العديد من التدابير الأمنية الإضافية، فإن العكس هو الحال في العالم الحقيقي.

في عام 2007، كانت هناك أول طروادة مصممة خصيصًا والتي سرقت المعلومات من الإنترانت، وهي موقع الويب الخاص بـ "مونستر لأرباب العمل" لموقع Monster.com، وهو تطبيق ويب للتعيين عبر الإنترنت. تعد أحصنة طروادة المصممة خصيصًا نادرة جدًا حتى الآن، والمخاطر منخفضة جدًا، ولكنها بالتأكيد تمثل إمكانية ومثالًا على أهمية أمان مضيف العميل أيضًا. ومع ذلك، فإن التهديد الأعلى للتطبيقات الداخلية والإدارة هو XSS و CSRF.

XSS إذا كان التطبيق الخاص بك يعيد عرض مدخلات المستخدم الضار من الشبكة الخارجية، فسيكون التطبيق عرضة لـ XSS. أسماء المستخدمين، التعليقات، تقارير الرسائل غير المرغوب فيها، عناوين الطلبات هي مجرد أمثلة قليلة غير مألوفة، حيث يمكن أن يكون هناك XSS.

وجود مكان واحد في واجهة الإدارة أو الإنترانت، حيث لم تُطهر المدخلات، يجعل التطبيق بأكمله عرضة للخطر. تشمل عمليات الاستغلال المحتملة سرقة ملف تعريف الارتباط الخاص بالمسؤول، وحقن iframe لسرقة كلمة مرور المسؤول أو تثبيت برامج ضارة من خلال ثغرات أمنية للمتصفح لتولي جهاز الكمبيوتر الخاص بالمشرف.

ارجع إلى قسم الحقن للتعامل مع الإجراءات المضادة مقابل XSS.

التزوير عبر الموقع CSRF طلب التزوير (CSRF)، المعروف أيضا باسم التزوير المرجعي عبر المواقع (XSRF)، هو أسلوب هجوم عملاق، فإنه يسمح للمهاجم بالقيام بكل شيء قد يفعله المسؤول أو مستخدم الإنترانت. كما سبق أن رأينا أعلاه كيف يعمل CSR، إليك بعض الأمثلة لما يمكن أن يفعله المهاجمون في واجهة الإنترانت أو الإدارة.

مثال حقيقي هو إعادة تشكيل جهاز التوجيه بواسطة CSRF. أرسل المهاجمون بريدًا إلكترونيًا ضارًا، مع CSRF فيه، إلى المستخدمين المكسيكيين. زعم البريد الإلكتروني أن هناك بطاقة إلكترونية في انتظار المستخدم، ولكنها احتوت أيضًا على علامة صورة أدت إلى طلب HTTP-GET لإعادة تكوين جهاز توجيه المستخدم (وهو نموذج مشهور في المكسيك). غيَّر الطلب إعدادات نظام أسماء النطاقات (DNS) بحيث تعين طلبات موقع مصرفي مقره في المكسيك لموقع المهاجم. كل من وصل إلى الموقع المصرفي من خلال ذلك الراوتر رأى موقع المهاجم المزيّف على شبكة الإنترنت وسرقت أوراق اعتماده.

مثال آخر غير عنوان البريد الإلكتروني وكلمة مرور Google Adsense. إذا سُجل الضحية في جوجل أدسنس، واجهة الإدارة لحملات الإعلان جوجل، يستطيع المهاجم تغيير أوراق اعتماد الضحية.

هناك هجوم شائع آخر هو إرسال بريد إلكتروني غير مرغوب فيه إلى تطبيق الويب الخاص بك أو مدونتك أو المنتدى الخاص بك لنشر XSS ضار. بالطبع، يجب على المهاجم معرفة بنية عنوان URL، ولكن معظم عناوين URL Rails واضحة تمامًا أو يسهل اكتشافها، إذا كانت واجهة إدارية للتطبيق مفتوح المصدر. قد يخمن المهاجم 1000 تخمين محظوظ فقط من خلال تضمين علامات IMG الخبيثة التي تحاول إجراء كل تركيبة ممكنة.

للتدابير المضادة ضد CSRF في واجهات الإدارة والتطبيقات Intranet، ارجع إلى التدابير المضادة في قسم CSRF.

الاحتياطات الإضافية

تعمل واجهة الإدارة العامة بالشكل التالي: إنها موجودة على www.example.com/admin، ولا يمكن الوصول إليها إلا إذا تعين علامة المشرف في نموذج المستخدم، وتعرض إعادة إدخال المستخدم وتسمح للمشرف بحذف / إضافة / تعديل أي شيء من البيانات المطلوبة. إليك بعض الأفكار حول هذا:

  • من المهم جدًا التفكير في أسوأ الحالات: ماذا لو كان شخص ما قد احتفظ بملفات تعريف الارتباط أو بيانات اعتماد المستخدم. يمكنك تقديم أدوار للواجهة الإدارية للحد من إمكانيات المهاجم. وماذا عن بيانات اعتماد تسجيل الدخول الخاصة لواجهة الإدارة، بخلاف تلك المستخدمة للجزء العام من التطبيق. أو كلمة مرور خاصة لاتخاذ إجراءات خطيرة للغاية؟
  • هل يجب على المشرف حقًا الوصول إلى الواجهة من كل مكان في العالم؟ نفكر في الحد من تسجيل الدخول إلى مجموعة من عناوين IP المصدر. افحص request.remote_ip لمعرفة عنوان IP للمستخدم. هذه ليست واقية من الرصاص، ولكن حاجز كبير. تذكر أنه قد يكون هناك بروكسي قيد الاستخدام.
  • ضع واجهة الإدارة على نطاق فرعي خاص مثل admin.application.com واجعله تطبيقًا منفصلاً مع إدارة المستخدم الخاصة به. هذا يجعل سرقة ملف تعريف ارتباط مسؤول من النطاق المعتاد، www.application.com، مستحيل. هذا بسبب نفس سياسة الأصل في المستعرض الخاص بك: قد لا يُقرأ البرنامج النصي الذي حُقن (XSS) على www.application.com ملف تعريف الارتباط لـ admin.application.com والعكس بالعكس.

إدارة المستخدم

يجب أن يتعامل كل تطبيق ويب تقريبًا مع التفويض والاستيثاق. وبدلاً من أن تتجول بنفسك، من المستحسن استخدام المكونات الإضافية الشائعة. ولكن ابقهم محدثين أيضًا. يمكن أن تؤدي بعض الاحتياطات الإضافية إلى جعل تطبيقك أكثر أمانًا.

هناك عدد من المكونات الإضافية للاستيثاق متاحة في Rails. هناك اخرى جيدة، مثل الاستنباط ومنطق الاستيثاق، تخزن فقط كلمات المرور المشفرة، وليس كلمات المرور ذات النص العادي. في Rails 3.1، يمكنك استخدام التابع has_secure_password المضمّن الذي يحتوي على ميزات مشابهة.

يحصل كل مستخدم جديد على رمز تنشيط لتفعيل حسابه عندما يتلقى رسالة إلكترونية تحتوي على رابط فيه. بعد تنشيط الحساب، تعين أعمدة activation_code إلي NULL في قاعدة البيانات. إذا طلب شخص ما عنوان URL كهذا، يُسجيل دخوله كأول مستخدم نشط موجود في قاعدة البيانات (ومن المحتمل أن يكون هذا هو المسؤول):

http://localhost:3006/user/activate

http://localhost:3006/user/activate?id=

هذا ممكن لأنه على بعض الخوادم، بهذه الطريقة، يكون معرف المعامل، كما هو الحال في [params [: id، لا شيء. ومع ذلك، هنا هو الباحث عن إجراء التنشيط:

User.find_by_activation_code(params[:id])

إذا كان المعامل لا شيء، فسيكون استعلام SQL الناتج

SELECT * FROM users WHERE (users.activation_code IS NULL) LIMIT 1

وبالتالي وجدت أول مستخدم في قاعدة البيانات، و أعادته وسجله. يمكنك معرفة المزيد عنه في هذا المنشور. من المستحسن تحديث المكونات الإضافية من وقت لآخر. علاوة على ذلك، يمكنك مراجعة طلبك للعثور على المزيد من العيوب على هذا النحو.

حسابات فرض الإجبار

ملاحظة: هجمات القوة العمياء في الحسابات هي هجمات تجريبية وأخطاء على بيانات اعتماد تسجيل الدخول. صدهم مع المزيد من رسائل الخطأ العامة وربما تتطلب إدخال اختبار CAPTCHA.

قد يُساء استخدام قائمة بأسماء المستخدمين لتطبيق الويب الخاص بك لفرض كلمات المرور المقابلة، لأن معظم الأشخاص لا يستخدمون كلمات مرور معقدة. معظم كلمات المرور هي مزيج من الكلمات القاموس وربما الأرقام. إذا سُلحت بقائمة أسماء المستخدمين والقواميس، فقد يجد البرنامج التلقائي كلمة المرور الصحيحة في غضون دقائق.

وبسبب هذا، فإن معظم تطبيقات الويب تعرض رسالة خطأ عامة "اسم المستخدم أو كلمة المرور غير صحيحة"، إذا كان أحدها غير صحيح. إذا قال "لم يعثر على اسم المستخدم الذي ادخلته"، يمكن للمهاجم تلقائياً تجميع قائمة بأسماء المستخدمين.

ومع ذلك، ما يهمل معظم مصممي تطبيقات الويب، هي صفحات نسيت كلمة المرور. تعترف هذه الصفحات غالبًا بأن اسم المستخدم أو عنوان البريد الإلكتروني الذي أُدخل لم يعثر عليه. هذا يسمح للمهاجم بتجميع قائمة بأسماء المستخدمين والقوة العمياء للحسابات.

للتخفيف من مثل هذه الهجمات، اعرض رسالة خطأ عامة على صفحات نسيت كلمة المرور أيضًا. علاوة على ذلك، يمكنك طلب إدخال اختبار CAPTCHA بعد عدد من عمليات تسجيل الدخول الفاشلة من عنوان IP معين. ومع ذلك، لاحظ أن هذا ليس حلًا مضادًا للرصاص ضد البرامج التلقائية، لأن هذه البرامج قد تغير عنوان IP الخاص بها تمامًا كما هو الحال دائمًا. ومع ذلك، فإنه يثير حاجز الهجوم.

اختطاف الحساب

تسهل العديد من تطبيقات الويب اختطاف حسابات المستخدمين. لماذا لا تكون مختلفة وجعلها أكثر صعوبة؟

كلمات السر

فكر في الموقف الذي سرق فيه أحد المهاجمين ملف تعريف ارتباط جلسة المستخدم، ومن ثم يمكنه استخدام التطبيق. إذا كان من السهل تغيير كلمة المرور، سيختطف المهاجم الحساب بنقرات قليلة. أو إذا كان نموذج تغيير كلمة المرور عرضة لـ CSRF، سيغير المهاجم كلمة المرور الخاصة بالضحية عن طريق إغرائهم إلى صفحة ويب تحتوي على علامة IMG صُممت باستخدام CSRF. كإجراء مضاد، تأكد من أن نماذج كلمة مرور التغيير آمنة ضد CSRF، بالطبع. وتطلب من المستخدم إدخال كلمة المرور القديمة عند تغييرها.

البريد الإلكتروني

ومع ذلك، قد يسيطر المهاجم أيضًا على الحساب عن طريق تغيير عنوان البريد الإلكتروني. بعد تغييرها، ينتقل إلى صفحة كلمة المرور المنسية وسترسل كلمة المرور (قد تكون جديدة) إلى عنوان البريد الإلكتروني للمهاجم. كإجراء مضاد، يطلب من المستخدم إدخال كلمة المرور عند تغيير عنوان البريد الإلكتروني أيضًا.

الآخرى

اعتمادًا على تطبيق الويب الخاص بك، قد يكون هناك المزيد من الطرق لاختطاف حساب المستخدم. في العديد من الحالات، يساعد CSRF و XSS في القيام بذلك. على سبيل المثال، كما هو الحال في ثغرة CSRF في Google Mail. في هجوم إثبات المفهوم هذا، كان الضحية قد اغري إلى موقع ويب يسيطر عليه المهاجم. في هذا الموقع عبارة عن علامة IMG وضعت وينتج عنها طلب HTTP GET يغير اعدادات فلتر Google Mail. إذا سجل الضحية في Google Mail، سيغير المهاجم الفلاتر لإعادة توجيه جميع رسائل البريد الإلكتروني إلى عنوان البريد الإلكتروني الخاص بهم. هذا يماثل ضررًا تمامًا مثل اختطاف الحساب بالكامل. كتدبير مضاد، راجع منطق التطبيق الخاص بك وأزل كل ثغرات XSS و CSRF.

CAPTCHAs

ملاحظة: اختبار CAPTCHA هو اختبار استجابة تحديدي لتحديد أن الاستجابة لا تُنشأ بواسطة جهاز كمبيوتر. وغالبًا ما يستخدم لحماية نماذج التسجيل من المهاجمين ونماذج التعليقات من برامج التتبع العشوائية التلقائية عن طريق مطالبة المستخدم بكتابة حروف صورة مشوهة. هذا هو اختبار CAPTCHA الإيجابي، ولكن هناك أيضًا اختبار CAPTCHA السلبي. إن فكرة اختبار CAPTCHA السلبي ليست للمستخدم أن يثبت أنه إنسان، ولكنه يكشف أن الروبوت هو إنسان آلي.

واجهة برمجة تطبيقات CAPTCHA إيجابية شائعة هي reCAPTCHA التي تعرض صورتين مشوهتين للكلمات من الكتب القديمة. كما أنه يضيف خطًا مائلًا، بدلاً من خلفية مشوهة ومستويات عالية من التشويش على النص كما كان يفعل اختبار CAPTCHA سابقًا، لأنه كُسرهذا الأخير. كمكافأة، يساعد استخدام reCAPTCHA في تحويل الكتب القديمة إلى رقمية. ReCAPTCHA هو أيضًا مكون إضافي Rails يحمل نفس اسم واجهة برمجة التطبيقات.

ستحصل على مفتاحين من واجهة برمجة التطبيقات (API)، عام ومفتاح خاص، يجب عليك وضعه في بيئة Rails لديك. بعد ذلك يمكنك استخدام التابع recaptcha_tags في الواجهة، و verification_recaptcha في وحدة التحكم. سيرجع  Verify_recaptcha خطأ إذا فشل التحقق من الصحة. تكمن المشكلة في CAPTCHA في أن لها تأثيرًا سلبيًا على تجربة المستخدم. بالإضافة إلى ذلك، وجد بعض المستخدمين المعاقين بصريًا أن بعض أنواع اختبارات CAPTCHA المشوهة يصعب قراءتها. ومع ذلك، تعد اختبارات CAPTCHA الإيجابية إحدى أفضل الطرق لمنع جميع أنواع برامج التتبع من إرسال النماذج.

معظم البوتات غبية حقا. إنهم يزحفون على الويب ويضعون بريدهم الإلكتروني غير المرغوب فيه في كل حقل يمكنهم العثور عليه. تستفيد اختبارات CAPTCHA السلبية من ذلك وتتضمن حقل "honeypot" في النموذج الذي سيخفي عن المستخدم البشري من خلال CSS أو جافا سكريبت.

تجدر الإشارة إلى أن اختبار CAPTCHA السلبي لا يكون فعالًا إلا ضد برامج التتبع البكم ولا يكفي لحماية التطبيقات المهمة من برامج التتبع المستهدفة. ومع ذلك، يمكن الجمع بين اختبار CAPTCHA السلبي والإيجابي لزيادة الأداء، على سبيل المثال، إذا لم يكن حقل "honeypot" فارغًا (اُكتشف)، فلن تحتاج إلى التحقق من اختبار CAPTCHA الإيجابي، والذي يتطلب طلب HTTPS إلى Google ReCaptcha قبل حساب الاستجابة.

فيما يلي بعض الأفكار حول كيفية إخفاء حقول honeypot بواسطة JavaScript و / أو CSS:

  • ضع الحقول خارج المنطقة المرئية من الصفحة.
  • جعل العناصر صغيرة جدًا أو تلوينها بنفس خلفية الصفحة.
  • اترك الحقول معروضة، ولكن أخبر البشر بتركها فارغة.

يعتبر اختبار CAPTCHA السلبي الأكثر بساطة هو حقل honeypot مخفي واحد. على جانب الخادم، ستتحقق من قيمة الحقل: إذا كان يحتوي على أي نص، فيجب أن يكون عبارة عن برنامج تتبع. بعد ذلك، يمكنك إما تجاهل المشاركة أو إظهار نتيجة إيجابية، ولكن لا يمكنك حفظ المشاركة في قاعدة البيانات. بهذه الطريقة سوف يكون bot راضيًا ويتحرك.

يمكنك العثور على اختبارات CAPTCHA سلبية أكثر تعقيدًا في مشاركة مدونة Ned Batchelder:

  • تضمين حقل مع الطابع الزمني UTC الحالي فيه والتحقق من ذلك على الخادم. إذا كان بعيدًا جدًا في الماضي، أو إذا كان في المستقبل، فإن النموذج غير صالح.
  • عشوائية أسماء الحقول.
  • ضمن أكثر من حقل honeypot من جميع الأنواع، بما في ذلك أزرار الإرسال.

لاحظ أن هذا لا يحميك إلا من البوتات التلقائية، ولا يمكن إيقاف برامج التتبع المستهدفة المخصصة لذلك. لذلك قد لا تكون اختبارات CAPTCHA السلبية جيدة لحماية نماذج تسجيل الدخول.

التسجيل

أخبر Rails بعدم وضع كلمات المرور في ملفات السجل.

بشكل افتراضي، تسجل Rails جميع الطلبات التي أجريت على تطبيق الويب. ولكن ملفات السجل يمكن أن تكون مشكلة أمنية كبيرة، لأنها قد تحتوي على بيانات اعتماد تسجيل الدخول وأرقام بطاقات الائتمان وما إلى ذلك. عند تصميم مفهوم أمان تطبيق ويب، يجب أن تفكر أيضًا في ما سيحدث إذا حصل أحد المهاجمين على (الوصول الكامل) إلى خادم الويب. سيكون تشفير الأسرار وكلمات المرور في قاعدة البيانات غير ذي جدوى، إذا كانت ملفات السجل تسردها بنص واضح. يمكنك تصفية معاملات طلب معينة من ملفات السجل الخاصة بك عن طريق إلحاقها بـ config.filter_parameters في تكوين التطبيق. توضع علامة على هذه المعاملات

[FILTERED] في السجل.

config.filter_parameters << :password

ملاحظة: ترشح المعاملات المقدمة بواسطة التعبير العادي المطابق الجزئي. يضيف Rails الافتراضي: كلمة المرور في المهيأ المناسب (initializers / filter_parameter_logging.rb) وتهتم بمعاملات كلمة المرور النموذجية وكلمة password_confirmation.

كلمات المرور الجيدة

ملاحظة: هل تجد صعوبة في تذكر كل كلمات المرور الخاصة بك؟ لا تدونها، ولكن استخدم الحروف الأولية لكل كلمة في جملة سهلة التذكر.

قام بروس شناير، وهو تقني أمني، بتحليل 34000 اسم مستخدم وكلمة مرور في العالم الحقيقي من هجوم MySpace للتصيد الاحتيالي المذكور أدناه. اتضح أن معظم كلمات المرور من السهل جدًا اختراقها. كلمات المرور العشرين الأكثر شيوعًا هي:

password1, abc123, myspace1, password, blink182, qwerty1, ****you, 123abc, baseball1, football1, 123456, soccer, monkey1, liverpool1, princess1, jordan23, slipknot1, superman1, iloveyou1, and monkey.

من المثير للاهتمام أن 4٪ فقط من كلمات المرور هذه كانت كلمات معجم وأن الأغلبية العظمى هي أبجدية رقمية. ومع ذلك، تحتوي يستخدم روبي نهجًا مختلفًا بعض الشيء عن العديد من اللغات الأخرى لتتطابق مع نهاية وبداية السلسلة. هذا هو السبب في أن العديد من كتب روبي ورييلز يخطئون. إذن كيف يكون هذا تهديدًا أمنيًا؟ لنفترض أنك تريد التحقق من صحة حقل عنوان URL بشكل غير صحيح وأنك استخدمت تعبيرًا عاديًا بسيطًا كالتالي:قواميس تكرارات كلمة المرور على عدد كبير من كلمات المرور اليوم، وتجربة جميع أنواع تركيبات (أبجدية). إذا كان المهاجم يعرف اسم المستخدم الخاص بك وكنت تستخدم كلمة مرور ضعيفة، سيخترق حسابك بسهولة.

كلمة المرور الجيدة هي تركيبة أبجدية رقمية طويلة من الحالات المختلطة. بما أنه من الصعب تذكر ذلك، فمن المستحسن أن ندخل فقط الأحرف الأولى من الجملة التي يمكنك تذكرها بسهولة. على سبيل المثال "The quick brown fox jumps over the lazy dog" سيكون "Tqbfjotld". لاحظ أن هذا مجرد مثال، يجب ألا تستخدم عبارات معروفة مثل هذه، كما قد تظهر في قواميس التكسير، أيضًا.

التعبيرات العادية

ملاحظة: من الوقائع الشائعة في تعبيرات Ruby العادية هي مطابقة بداية السلسلة ونهايتها بـ ^ و $ ، بدلاً من \ A و \ z.

يستخدم روبي نهجًا مختلفًا بعض الشيء عن العديد من اللغات الأخرى لتتطابق مع نهاية وبداية السلسلة. هذا هو السبب في أن العديد من كتب Ruby و Rails يخطئون. إذن كيف يكون هذا تهديدًا أمنيًا؟ لنفترض أنك تريد التحقق من صحة حقل عنوان URL بشكل غير صحيح وأنك استخدمت تعبيرًا عاديًا بسيطًا كالتالي:

/^https?:\/\/[^\n]+$/i

هذا قد يعمل بشكل جيد في بعض اللغات. ومع ذلك، في روبي ^ و $ يطابق خط البداية ونهاية الخط. وبالتالي فإن عنوان URL مثل هذا يمرر الفلتر بدون مشاكل:

javascript:exploit_code();/*

http://hi.com

*/

يجتاز عنوان URL هذا الفلتر؛ لأن التعبير العادي يطابق - السطر الثاني، لا يهم البقية. الآن تخيل أنه لدينا عرضًا أظهر عنوان URL مثل هذا:

link_to "Homepage", @user.homepage

يبدو الارتباط بريئًا للزائرين، ولكن عند النقر عليه، ينفذ وظيفة JavaScript "exploit_code" أو أي JavaScript آخر يوفره المهاجم.

لإصلاح التعبير العادي، يجب استخدام \ A و \ z بدلاً من ^ و $، مثل:

/\Ahttps?:\/\/[^\n]+\z/i

بما أن هذا خطأ متكرر، فإن مدقق الصيغة (validates_format_of) يطرح الآن استثناء إذا كان التعبير العادي المقدم يبدأ بـ ^ أو ينتهي بـ $. إذا كنت بحاجة إلى استخدام ^ و $ بدلاً من \ A و \ z (وهو أمر نادر الحدوث)، فيمكنك تعيين: خيار متعدد الأسطر إلى true، مثل:

# content should include a line "Meanwhile" anywhere in the string

validates :content, format: { with: /^Meanwhile$/, multiline: true }

لاحظ أن هذا لا يحميك إلا من الخطأ الأكثر شيوعًا عند استخدام أداة التحقق من الصيغة - عليك دائمًا أن تضع في اعتبارك أن ^ و $ يتطابقان مع بداية السطر ونهاية السطر في Ruby، وليس بداية ونهاية السلسلة.

تصعيد الصلاحيات

ملاحظة: قد يؤدي تغيير معامل واحد إلى منح المستخدم وصولاً غير مصرح به. تذكر أنه قد يتغير كل معامل، بغض النظر عن مدى إخفاءه أو تشويشه.

المعامل الأكثر شيوعًا التي قد يعبث بها المستخدم هو معامل المعرّف، كما هو الحال في http://www.domain.com/project/1، في حين أن الرقم 1 هو المعرف. سوف تكون متاحة في params في وحدة تحكم. هناك، على الأرجح ستفعل شيئًا كالتالي:

@project = Project.find(params[:id])

هذا أمر لا بأس به بالنسبة لبعض تطبيقات الويب، ولكن بالتأكيد ليس إذا كان المستخدم غير مخول لعرض جميع المشاريع. إذا غيّر المستخدم المعرف إلى 42، ولا يُسمح له برؤية تلك المعلومات، فسيكون بإمكانه الوصول إليها على أي حال. بدلاً من ذلك، استفسر عن حقوق وصول المستخدم أيضًا:

@project = @current_user.projects.find(params[:id])

اعتمادًا على تطبيق الويب الخاص بك، سيكون هناك العديد من المعاملات التي يمكن للمستخدم التلاعب بها. كقاعدة عامة، لا توجد بيانات إدخال المستخدم آمنة، حتى يثبت العكس، ومن المحتمل أن يتعامل مع كل معامل من المستخدم.

لا تنخدع بالأمن عن طريق التعتيم وأمن JavaScript. تتيح لك أدوات المطوّرين مراجعة الحقول المخفية لكل نموذج وتغييرها. يمكن استخدام JavaScript للتحقق من صحة بيانات إدخال المستخدم، ولكن بالتأكيد لا يمنع المهاجمين من إرسال طلبات ضارة ذات قيم غير متوقعة. تسجل الوظيفة الإضافية Firebug لـ Mozilla Firefox كل طلب وقد تكررها وتغيرها. هذه طريقة سهلة لتجاوز أي عمليات التحقق من جافا سكريبت. وهناك أيضًا البروكسي من جانب العميل تسمح لك باعتراض أي طلب واستجابة من وإلى الإنترنت.

الحقن

ملاحظة: الحقن هو فئة من الهجمات التي تدخل رمز أو معاملات ضارة في تطبيق ويب من أجل تشغيله ضمن سياق الأمان الخاص به. الأمثلة البارزة للحقن هي البرمجة عبر المواقع (XSS) وحقن SQL.

الحقن صعب للغاية، لأن نفس الكود أو المعامل يمكن أن تكون خبيثة في سياق واحد، ولكنها غير ضارة تمامًا في سياق آخر. يمكن أن يكون السياق عبارة عن لغة برمجة نصية أو استعلام أو لغة برمجة أو shell أو طريقة Ruby / Rails. تغطي الأقسام التالية جميع السياقات المهمة التي قد تحدث فيها هجمات الحقن. القسم الأول، ومع ذلك، يغطي قرار معماري فيما يتعلق حقن.

القوائم البيضاء والقوائم السوداء

ملاحظة: عند تطهير شيء ما أو حمايته أو التحقق منه، تفضل القوائم البيضاء فوق القوائم السوداء.

يمكن أن تكون القائمة السوداء قائمة بعناوين البريد الإلكتروني السيئة أو الإجراءات غير العامة أو علامات HTML غير الصحيحة. هذا يعارض القائمة البيضاء التي تسرد عناوين البريد الإلكتروني الجيدة، والإجراءات العامة، وعلامات HTML الجيدة وما إلى ذلك. على الرغم من أنه من غير الممكن في بعض الأحيان إنشاء قائمة بيضاء (في مرشح الرسائل الاقتحامية، على سبيل المثال)، تفضل استخدام طرق القائمة البيضاء:

  • استخدم before_action باستثناء: [...] بدلاً من فقط: [...] للإجراءات المتعلقة بالأمان. بهذه الطريقة لا تنس أن تقوم بتمكين التحقق من الأمان للإجراءات المضافة حديثًا.
  • اسمح باستخدام <strong> بدلاً من إزالة <script> ضد البرمجة النصية عبر المواقع (XSS). انظر أدناه للحصول على التفاصيل.
  • لا تحاول تصحيح إدخال المستخدم بواسطة القوائم السوداء:
  • هذا سيجعل الهجوم يعمل: ("","<sc<script>ript>".gsub("<script>"
  • لكن ارفض الإدخال غير الصحيح.

القوائم البيضاء هي أيضاً مقاربة جيدة ضد العامل البشري في نسيان شيء ما في القائمة السوداء.

حقن SQL

ملاحظة: وبفضل الأساليب الذكية، لا يعد ذلك مشكلة في معظم تطبيقات Rails. ومع ذلك، هذا هجوم مدمر وشائع في تطبيقات الويب، لذلك من المهم فهم المشكلة.

المقدمة

تهدف هجمات حقن SQL إلى التأثير على استعلامات قاعدة البيانات عن طريق معالجة معاملات تطبيق الويب. الهدف الشائع من هجمات حقن SQL هو تجاوز التفويض. هدف آخر هو تنفيذ معالجة البيانات أو قراءة البيانات التعسفية. في ما يلي مثال على كيفية عدم استخدام بيانات إدخال المستخدم في استعلام:

Project.where("name = '#{params[:name]}'")

قد يكون هذا في إجراء بحث ويمكن للمستخدم إدخال اسم مشروع يريد العثور عليه. إذا قام مستخدم ضار بإدخال --OR 1' فإن استعلام SQL الناتج سيكون:

SELECT * FROM projects WHERE name = ' ' OR 1 --'

تبدأ الشرطتان تعليقًا يتجاهل كل شيء بعده. لذا يرجع الاستعلام كافة السجلات من جدول المشاريع بما في ذلك المحجوبة للمستخدم. وذلك لأن الشرط صحيح لجميع السجلات.

تجاوز التخويل

عادة ما يتضمن تطبيق الويب التحكم في الوصول. يدخل المستخدم بيانات اعتماد تسجيل الدخول الخاصة بهم ويحاول تطبيق الويب العثور على السجل المطابق في جدول المستخدمين. يمنح التطبيق الوصول عندما يجد سجلاً. ومع ذلك، قد يتجاوز المهاجم هذا التحقق باستخدام إدخال SQL. يعرض المثال التالي استعلامًا نموذجيًا لقاعدة البيانات في Rails للعثور على السجل الأول في جدول المستخدمين الذي يطابق معاملات بيانات اعتماد تسجيل الدخول التي يوفرها المستخدم.

User.find_by("login = '#{params[:name]}' AND password = '#{params[:password]}'")

إذا قام المهاجم بإدخال 'OR' 1 '=' 1 كاسم، و 'OR' 2 '>' 1 ككلمة المرور، فسيكون استعلام SQL الناتج:

SELECT * FROM users WHERE login = '' OR '1'='1' AND password = '' OR '2'>'1' LIMIT 1

سيجد هذا ببساطة السجل الأول في قاعدة البيانات، ويمنح الوصول إلى هذا المستخدم.

قراءة غير مصرح بها

ربط العبارة UNION استعلامات SQL اثنين وإرجاع البيانات في مجموعة واحدة. يمكن للمهاجم استخدامه لقراءة البيانات التعسفية من قاعدة البيانات. لنأخذ المثال من الأعلى:

Project.where("name = '#{params[:name]}'")

والآن دعونا نحقن استعلام آخر باستخدام بيان UNION:

') UNION SELECT id,login AS name,password AS description,1,1,1 FROM users --

سيؤدي ذلك إلى استعلام SQL التالي:

SELECT * FROM projects WHERE (name = '') UNION

 SELECT id,login AS name,password AS description,1,1,1 FROM users --'

لن تكون النتيجة قائمة مشاريع (لأنه لا يوجد مشروع باسم فارغ)، ولكن قائمة بأسماء المستخدمين وكلمات المرور الخاصة بهم. نأمل أن تكون كلمات المرور مشفرة في قاعدة البيانات! المشكلة الوحيدة للمهاجم هي أن عدد الأعمدة يجب أن يكون هو نفسه في كلا الاستعلامات. هذا هو السبب في أن الاستعلام الثاني يتضمن قائمة بالأسماء (1)، والتي ستكون دائمًا القيمة 1، لمطابقة عدد الأعمدة في طلب البحث الأول.

أيضاً، يعيد الاستعلام الثاني تسمية بعض الأعمدة باستخدام عبارة AS بحيث يعرض تطبيق الويب القيم من جدول المستخدم. تأكد من تحديث Rails الخاصة بك إلى 2.1.1 على الأقل.

التدابير المضادة

يحتوي Ruby on Rails على فلتر مدمج لأحرف SQL الخاصة، والتي ستفوق "،"، حرف NULL وفواصل الأسطر. استخدم  

(Model.find(id او (Model.find_by_some thing(something يطبق هذا الإجراء تلقائيًا. ولكن في تجزئة SQL، خاصة في شروط التجزئة (where("...")) أو توابع ()connection.execute أو ()Model.find_by_sql، يجب أن تطبق يدويًا.

بدلاً من تمرير سلسلة إلى خيار الشروط، يمكنك تمرير مصفوفة لتعقيم السلاسل الملوثة مثل:

Model.where("login = ? AND password = ?", entered_user_name, entered_password).first

كما ترى، الجزء الأول من المصفوفة عبارة عن جزء SQL يحتوي على علامات استفهام. الإصدارات المعقمة للمتغيرات في الجزء الثاني من المصفوفة تحل محل علامات الاستفهام. أو يمكنك تمرير تجزئة لنفس النتيجة:

Model.where(login: entered_user_name, password: entered_password).first

نموذج المصفوفة أو التجزئة متاح فقط في الحالات النموذجية. يمكنك محاولة() sanitize_sql في مكان آخر. اجعلها عادة التفكير في العواقب الأمنية عند استخدام سلسلة خارجية في SQL.

البرمجة عبر المواقع (XSS)

ملاحظة: الأكثر انتشارًا، وأحد أكثر نقاط الضعف الأمنية تدميراً في تطبيقات الويب هو XSS. هذا الهجوم الخبيث يضخ رمزًا تنفيذيًا من جانب العميل. يوفر Rails طرق المساعد لإيقاف هذه الهجمات.

نقاط الدخول

نقطة الإدخال هي عنوان URL ضعيف ومعاملاته حيث يمكن للمهاجم بدء هجوم.

ونقاط الدخول الأكثر شيوعًا هي منشورات الرسائل وتعليقات المستخدمين وكتب الزائرين، ولكن عناوين المشروعات وأسماء المستندات وصفحات نتائج البحث كانت أيضًا عرضة - في كل مكان حيث يمكن للمستخدم إدخال البيانات. ولكن لا يجب بالضرورة أن تأتي المدخلات من مربعات الإدخال على مواقع الويب، يمكن أن تكون في أي معامل URL - واضحة أو مخفية أو داخلية. تذكر أن المستخدم قد اعترض أي حركة المرور. تجعل التطبيقات أو وكلاء موقع العميل من السهل تغيير الطلبات. هناك أيضا ناقلات هجوم أخرى مثل إعلانات لافتة.

يهاجم XSS العمل مثل هذا: يحقن أحد المهاجمين بعض الرموز، ويحفظه تطبيق الويب ويعرضه على صفحة، يُقدم لاحقًا إلى أحد الضحايا. تعرض معظم أمثلة XSS ببساطة صندوق تنبيه، لكنها أقوى من ذلك. يمكن لـ XSS سرقة ملف تعريف الارتباط، أو خطف الجلسة، أو إعادة توجيه الضحية إلى موقع ويب مزيف، أو عرض إعلانات لصالح المهاجم، أو تغيير العناصر على موقع الويب للحصول على معلومات سرية أو تثبيت برامج ضارة من خلال ثغرات أمنية في متصفح الويب.

خلال النصف الثاني من عام 2007، سجلت 88 نقطة ضعف في متصفحات موزيلا، 22 في سفاري، 18 في IE، و 12 في الأوبرا. كما وثق تقرير التهديدات العالمية لأمن الإنترنت من سيمانتك 239 نقطة ضعف في المتصفح في الأشهر الستة الأخيرة من عام 2007. ويعد Mpack إطارًا نشطًا وحديثًا للهجوم يستغل هذه الثغرات الأمنية. بالنسبة للمتسللين الإجراميين، فإنه من الأمور الجذابة للغاية استغلال ثغرة SQL-Injection في إطار تطبيق ويب وإدراج شفرة خبيثة في كل عمود جدول نصي. في أبريل / نيسان 200 ، اخترق أكثر من 510،000 موقع من هذا النوع، من بينها الحكومة البريطانية والأمم المتحدة والعديد من الأهداف البارزة.