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

تنشأ هذه الثغرة الأمنية عندما يسمح برنامج ما للمهاجم بإدخال بيانات غير موثوقة أو ضارة. يؤدي ذلك إلى قيام المفسّر (interpreter) بتنفيذ أوامر غير متوقعة، مما قد يكشف عن بيانات كان من المفترض أن تكون غير قابلة للوصول إليها، أو يتجاوز بعض إجراءات الأمان المطبقة. السبب الأكثر شيوعاً لثغرات حقن البيانات هو فشل البرنامج في تصفية (filter) أو التحقق من صحة (validate) أو تنقية (sanitize) مدخلات المستخدم. دعنا نلقي نظرة على مثالين لتطبيقات برمجية خاطئة تسمح بحدوث هجمات الحقن.
مثال على كود برمجي ضعيف 1: حقن NoSQL
لنفترض أن لديك مسار تسجيل دخول (login route) يستقبل بريداً إلكترونياً، ولأي سبب كان، يستقبل كلمة المرور مشفرة بالفعل.

إذا كنا نعرف عنوان البريد الإلكتروني لأحد المستخدمين، على سبيل المثال myemail@email.com، فيمكننا تجاوز نظام تسجيل الدخول هذا بسهولة عن طريق إرسال كائن JSON التالي، الذي يؤدي إلى حقن NoSQL:
{ "email" : "myemail@email.com" , "password" : { "$ne" : "" } }
هذا الكائن سيوجه قاعدة بيانات MongoDB للبحث عن مستخدم بالبريد الإلكتروني "myemail@email.com" وكلمة مرور مختلفة عن سلسلة نصية فارغة. قد يبدو هذا المثال بعيد المنال قليلاً، لكن ألقِ نظرة على الكود التالي وحاول تحديد المشكلة.
مثال على كود برمجي ضعيف 2: حقن الخصائص
في هذا المثال، لدينا نموذج تسجيل (registration form) على الواجهة الأمامية، مع الكود التالي في الواجهة الخلفية (back-end):


كيف يمكننا استغلال هذا الكود؟ الأمر بسيط جداً: لنفترض أن مخطط المستخدم (User Schema) يبدو كالتالي:
export const UserSchema = new mongoose.Schema({
email : {
type : String ,
required : true ,
unique : true
},
password : {
type : String ,
required : true
},
admin : {
type : Boolean ,
default : false
},
accountConfirmed : {
type : Boolean ,
default : false
},
},
);
الآن، ما عليك سوى إرسال طلب POST التالي باستخدام Postman أو أي أداة أخرى تفضلها:
{ "email" : "my-email" , "password" : "123321" , "admin" : "true" , "accountConfirmed" : "true" }
وبهذا تكون قد سجلت بنجاح في هذا الموقع – ليس كمستخدم عادي، بل بحساب مسؤول (admin) مؤكد. تكمن المشكلة هنا في أنه إذا استخدمنا ببساطة:
{ ...req.body }
فسنقوم بإنشاء كائن مستخدم جديد بجميع الخصائص الموجودة داخل جسم الطلب (object body)، وبالتالي يمكننا حقن أي شيء نريده.
إعادة هيكلة الكود لمنع هجمات الحقن
دعنا نعيد هيكلة الكود من كلا المثالين لمنع هذا النوع من الهجمات.
بالنسبة للمثال الأول، يمكننا التحقق من النوع المتوقع لكل من البريد الإلكتروني وكلمة المرور. في حالتنا، نتوقع سلسلة نصية (string) في كلا الحقلين:

إذا قدمنا نفس المعاملات مرة أخرى:
{ "email" : "myemail@email.com" , "password" : { "$ne" : "" } }
سنتلقى استجابة 400 Bad Request (طلب سيء). يمكننا المضي أبعد من ذلك والتحقق مما إذا كان البريد الإلكتروني هو بالفعل بريد إلكتروني وليس مجرد سلسلة نصية بسيطة، لكن هذا خارج نطاقنا حالياً.
بالنسبة للمثال الثاني، يمكننا استخدام التحقق من صحة المدخلات من جانب الخادم (server-side input validation) بأسلوب “القائمة البيضاء” (whitelist) عن طريق تجريد الخصائص غير المرغوب فيها:

كانت هذه الأمثلة خاصة بحقن NoSQL، ولكن يمكن توسيع هذه التقنية لتشمل حقن SQL أيضاً.
استخدام مكونات ذات ثغرات أمنية معروفة

لقد رأينا أعلاه بعض معايير الأمان التي تم تطبيقها بشكل سيء والتي نتجت عن أخطائنا. ومع ذلك، هناك مواقف لا تكون فيها المشكلة من الكود الذي كتبناه بأنفسنا، بل من الكود مفتوح المصدر (open-source) الذي نستخدمه في مشروعنا. يمكن للمهاجم استغلال ثغرات هذه المكونات لتنفيذ تعليمات برمجية ضارة أو لجعل البرنامج يتصرف بطريقة غير مرغوبة.
على الرغم من أن هذا قد يبدو خارج سيطرتك، إلا أنه ليس كذلك. هناك خطوات يمكننا اتخاذها لمنع هذا النوع من المشكلات. على سبيل المثال، يمكننا إجراء جرد مستمر لإصدارات المكونات لكل من جانب العميل (client-side) وجانب الخادم (server-side)، وإزالة التبعيات (dependencies) و/أو الميزات غير المستخدمة. كما يمكننا مراقبة المصادر بحثاً عن الثغرات الأمنية في المكونات.

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

تظهر هذه الثغرة الأمنية عندما تطبق تطبيقات الويب تقنيات المصادقة (authentication) أو إدارة الجلسات (session management) بشكل سيء. يؤدي هذا إلى منح المهاجمين إمكانية الوصول إلى حسابات لا ينبغي أن يكونوا مخولين بالوصول إليها. تنتشر هذه المشكلة الأمنية بشكل خاص في شكل هجمات القوة الغاشمة (brute force attacks) وعندما يتم كشف معرفات الجلسة (session-ids) أو الرموز المميزة (tokens) بطريقة يمكن سرقتها بسهولة.
مثال على كود برمجي ضعيف 1: هجمات القوة الغاشمة
دعنا نأخذ المثال من مقتطف الكود السابق. قمنا بتعديله قليلاً لإرسال استجابة 401 (Unauthorized) عندما لا يتم العثور على مستخدم ببريد إلكتروني وكلمة مرور معينين.

على الرغم من أن هذا هو الكود المعاد هيكلته، إلا أنه لا يزال عرضة لثغرة المصادقة المعطلة. هنا، إذا استخدمنا كلمة مرور خاطئة، نحصل على استجابة 401. ولكن إذا كانت كلمة المرور ضعيفة، يمكننا شن هجوم القوة الغاشمة عليها حتى نخمنها.
إعادة هيكلة الكود: منع هجمات القوة الغاشمة
يمكننا منع هجمات القوة الغاشمة ببساطة عن طريق استخدام تحديد المعدل (rate limit) على مسارنا. الآن، يمتلك المستخدم 3 فرص للمصادقة، وبعد ذلك لن يتمكن من إرسال طلبات على هذا المسار لمدة 15 دقيقة القادمة (وسيتلقى استجابة 429 Too many requests).

مثال على كود برمجي ضعيف 2: إدارة رموز JWT
النوع التالي من الثغرات الأمنية في هذا الموضوع يتعلق بشكل خاص بسوء إدارة رموز الويب JSON (JSON Web Token - JWT).
المثال التالي شائع جداً في أنظمة تسجيل الدخول:

في معظم الأحيان، يتم تطبيق نظام تسجيل الدخول الذي يستخدم JWT بهذه الطريقة. بعد أن يرسل المستخدم بيانات الاعتماد الصحيحة، يتم إنشاء رمز مميز باستخدام معرفه (id) أو قيمة فريدة أخرى. ثم يتم إرسال الرمز المميز إلى الواجهة الأمامية (front-end) حيث سيتم حفظه داخل التطبيق. أو إذا كانت هناك حاجة إلى مصادقة مستمرة، فسيتم حفظه داخل ملفات تعريف الارتباط (cookies) أو التخزين المحلي (local storage).
المشكلة في هذا النهج هي أن الرمز المميز الذي يجب أن يكون آمناً يمكن الوصول إليه الآن من خلال كود الواجهة الأمامية، مما يجعله عرضة للاختراق. يمكن للكود الضار المحقون في جافاسكريبت الواجهة الأمامية الوصول إلى ملفات تعريف الارتباط أو التخزين المحلي وسرقة هذا الرمز المميز.
إعادة هيكلة الكود: تأمين رموز JWT
يمكن التغلب على هذه المشكلة بالتطبيق التالي:

هذه المرة، يتم حفظ الرمز المميز أيضاً في ملفات تعريف الارتباط (cookies)، ولكن يتم حفظه من كود الواجهة الخلفية (back-end) باستخدام خاصية httpOnly. هذا يعني أنه لا يمكن الوصول إليه من أي كود يعمل على الواجهة الأمامية (front-end). لجعله أكثر أماناً، يتم حفظ الرمز المميز مع خاصية signed، مما يتسبب في توقيع ملفات تعريف الارتباط بمفتاح سري. يمكنك المضي أبعد من ذلك وحظر بروتوكول HTTP باستخدام علامة secure flag التي تفرض إرسال ملف تعريف الارتباط عبر HTTPS.
كشف البيانات الحساسة (Sensitive Data Exposure)

كما يوحي الاسم، تظهر هذه الثغرة الأمنية عندما يفشل تطبيق الويب في حماية البيانات الحساسة بشكل كافٍ. بينما تهدف التغييرات القانونية الأخيرة مثل اللائحة العامة لحماية البيانات (GDPR) إلى ضمان عدم كشف البيانات الحساسة، إلا أن نسبة كبيرة من تطبيقات الويب تفشل في تلبية هذه المتطلبات.
يحدث هذا عادة عندما يتم نقل البيانات بنص واضح (clear text) باستخدام بروتوكولات مثل HTTP و SMTP و FTP، أو عند استخدام خوارزميات تشفير ضعيفة أو قديمة.
سيناريو محتمل يمكن أن يكون كالتالي: موقع ويب لا يستخدم أو يفرض TLS لجميع الصفحات. يقوم المهاجم بمراقبة حركة مرور الشبكة، ويخفض مستوى الاتصالات من HTTPS إلى HTTP، ويعترض الطلبات، ويسرق المعلومات المرسلة. ربما يسرق حتى ملف تعريف الارتباط الخاص بجلسة المستخدم (session cookie)، وبالتالي يصل إلى بيانات المستخدم الخاصة أو يعدلها.
سيناريو آخر يمكن أن يكون: يتم تخزين كلمات المرور داخل قاعدة البيانات بدون “ملح” (unsalted) أو كـ “تجزئات” (hashes) بسيطة وضعيفة. يسمح عيب في تحميل الملفات أو أي هجوم آخر للمهاجم باسترداد قاعدة بيانات كلمات المرور. بعد ذلك، يمكن كشف جميع التجزئات باستخدام جدول قوس قزح (rainbow table) من القيم المحسوبة مسبقاً، مما يمنح المهاجم كلمة المرور الفعلية الواضحة للمستخدمين.
الخلاصة التقنية
في الختام، تُعد قائمة OWASP Top 10 دليلاً حيوياً للمطورين والمهندسين لتعزيز أمن تطبيقات الويب. لقد استعرضنا ثلاثاً من أخطر هذه الثغرات: حقن البيانات، استخدام المكونات ذات الثغرات المعروفة، والمصادقة المعطلة، مع تقديم أمثلة عملية وحلول لإعادة هيكلة الكود. يتطلب بناء تطبيقات ويب آمنة نهجاً استباقياً يركز على التحقق من المدخلات، وإدارة التبعيات (dependencies) بوعي، وتطبيق آليات مصادقة قوية. الالتزام بهذه الممارسات لا يحمي فقط بيانات المستخدمين، بل يعزز أيضاً سمعة التطبيق ويضمن امتثاله للمعايير الأمنية الحديثة.