Password reset vulnerabilities - ثغرات اعادة تعيين كلمة المرور

مقدمة

خاصية اعادة تعيين كلمة المرور من الخواص المهمة والخطيرة في نفس الوقت. مهمة لانها بتسهل علي المستخدمين تغيير الباسورد في حالة نسيانه بدون الرجوع لمدير الموقع او التطبيق خاصة لو تطبيق عليه مستخدمين كتير ودا بيخلي من المستحيل ان مدير الموقع يبقي هو المسئول عن عملية اعادة تعيين كلمات المرور للمستخدمين, وخاصية خطيرة لانها لو متصممتش صح او تم استخدمها في تطبيق ما بشكل غير اَمن هيؤدي في النهاية الي اختراق حسابات المستخدمين (Account Takeover)

الطرق المستخدمه في عملية اعادة تعيين كلمة المرور

1- استخدام ال PINs

وال PIN هو رمز مكون من مجموعة ارقام بيتراوح طوله بين 6 الي 12 رقم لما المستخدم بيحاول يعمل اعادة تعيين لكلمة المرور الموقع او التطبيق بيبعت ال PIN للمستخدم في رسالة SMS او علي ال E-mail الخاص بيه بعدين المستخدم بيبعت الرقم دا تاني للموقع مع الباسورد الجديد وبيتم تغيير الباسور

ايه هي الاخطاء او الثغرات اللي ممكن تكون موجودة مع الطريقة دي؟

1- عدم وجود حد لمعدل الطلبات (lack of rate limiting): عدم وجود حد لمعدل الطلبات بؤدي الي استغلال الثغرة دي عن طريق ال brute forcing وبتتم عن طريق ان ال attacker بيبعت طلب اعادة تعيين كلمة المرور لحساب شخص ما وبعدين بيبدأ يبعت طلبات كتير (bulk HTTP requests) لل endpoint المسؤلة عن اعادة تعيين كلمة المرور كل طلب بيروح معاه PIN مختلف, لحد ما الموقع يقبل ال PIN الصحيح

مثال: لو افترضنا ان example.com بيبعت للمستخدم للمستخدم PIN عبارة عن 6 ارقام علشان يعمل اعادة تعيين لكلمة المرور , المستخدم بياخد ال PIN وبعدين يبعته للموقع مع الباسورد الجديد

لو attacker حاول يعمل brute-force لل PIN هيبقا احتمالات الارقام بتتراوح بين 000000 و 999999 يعني معاه 100000 محاولة ممكن يكون PIN الصحيح في الاول او في الاخر و الرقم دا مش كبير ممكن تنفذ العملية دي من جهاز كمبيوتر شخصي ولو عايز تسرع العملية ممكن تستعين بال cloud

2- عدم التأكد من صلاحية ال PIN او lack of validation

بعد ما المستخدم بيبعت ال PIN والباسورد الجديد المفروض التطبيق يتأكد من كام حاجة كدا قبل ما يعمل تحديث للباسورد

+ يتاكد من صلاحية ال PIN بالنسبة للوقت. هل الPIN دا عدي الوقت المفترض لاستخدامة ولا ولا

+ يتأكد من ان الPIN دا هو الخاص بالمستخدم

+ ياكد اذا كان موجود في قاعدةالبيانات من الاساس ولا لا

+ يتأكد اذا كان تم استخدام ال PIN قبل كدا ولا لا

ايه اللي يحصل لو التطبيق مش بينفذ الخطوات السابقة؟

لو مش بيتاكد من وقت اصدار ال PIN بالتالي ال PIN هيفضل صالح للاستخدام لفترة طولية فلو شخص قدر يوصل لل PIN عن طريق انو قدر يقرأ ال SMS او ال Emails الخاصة بالضحية فأي وقت بقا له القدرة انه يعمل اعادة تعيين كلمة المرور لحساب المستخدم

وفي حالة تانية لو bad actor قدر يوصل لقاعدة البيانات التطبيق وكلمات مرور المستخدمين كانت متخزنة بطريقة اَمنة ممكن يعمل اعادة تعيين لكلمات المرور باستخدام ال PINs المتخزنة في قاعدة البيانات بدل ما يتعب نفسه في كسر كلمات المرور

ايه اللي يحصل لو التطبيق مش بيتأكد من ان ال PIN هو الخاص بالمستخدم؟

ممكن attacker يبعت طلب اعادة تعيين لكلمة المرور الخاصة بيه وبعيدن ياخد PIN ويستخدمة في اعادة تعيين كلمة مرور حساب تاني

ايه اللي يحصل لو التطبيق مش بيتأكد من وجود PIN في قاعدة البيانات؟

اي شخص ممكن يعمل اعادة تعيين لكلمة مرور شخص تاني بدون الحاجة لل PIN او ستخدام PIN بنفس الطول

ايه اللي يحصل لو التطبيق مش بيتأكد من ان ال PIN تم استخدامة قبل كدا ولا لا؟

مدي فاعلية الهجوم متوقفة علي اذا كان التطبيق بيتحقق من صلاحية ال PIN بالنسبة للوقت

3- عدم وجود عشواية في الارقام (lack of randomization)

لو مفيش عشوائية في اصدار ال PINs يعني لو مثلا بعت طلب اعادة تعيين كلمة المرور للحساب رقم 1 فال PIN كان 0000 ولما بعت للحساب رقم 2 ال pin كان 0001 بكدا ال PIN بقا قابل للتنبؤ يعني ممكن ابدأ ابعت طلبات لمجموعة من الحسابات وامشي بالترتيب لحد ما الاقي PIN الصحيح والطريقة دي مشابهة لل brute forcing ولاكن مع عدد طلبات اقل

الحلول لاستخدام ال PIN بشكل اَمن

1- اصدار PIN عشوائي لتجنب توقعه

2- ربط ال PIN بال user id في قاعدة البيانات لتجنب استخدام PIN صالح في اعادة تعيين كلمة المرور لحساب شخص تاني

3- تعيين وقت صلاحية لل PIN وميكونش وقت طويل(10 دقائق) لتجنب استخدام ال PIN مستقبلا

4- حد معدل الطلبات لتجنب هجوم ال brute forcing

5- ازالة ال PINs من قاعدة البيانات بعد استخدامها او بعد انتهاء مدة صلاحيتها

2- استخدام ال URL Tokens

ال token هو سلسلة من الحروف قد تكون عشوائية او غير عشوائية زي زي JWT (json web token) بنستخدمها علشان نعمل اعدادة تعيين كلمة المرور للمستخدم

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiSm9obiBEb2UiLCJ0b2tlbiI6ImFkZmFpY3ZuYWVmYT8ifQ.b1d34q0e32CKJm5SGc0HB1zwt4f5kmbV9hgZ-IbikM0

a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447

التطبيق بيبعتها للمستخدم علي الايميل بالشكل دا

https://example.com/password_reset?token=<token>

ايه هي الاخطاء والثغرات اللي ممكن تكون موجودة في الطريقة دي ؟

1- ال token قابل للتنبؤ

زي مثلا ان ال token يكون عبارة عن ال user id او ال username ولا كن بشكل يكون encoded زي ال base64 encoding فالظاهر ممكن يكون ان ال token عشوائي ولاكن في الحقيقة تقدر تعمل decode لل token وتعدل في براحتك

2- ال token بيتم تسريبه لمواقع تانيه عن طريق referer header

لو انت ببتصفح موقع X وفي رابط بيوديك علي موقع Y لو ضغط علي الرابط الrequest headers اللي راحة في الطلب بيكون من ضمنها header اسمها referer القيمة بتاعتها هي الرابط الخاص بالموقع اللي انت جاي منه اللي هو X

دلوقتي لو انت عايز تعمل اعادة تعيين لكلمة المرور وبعدين فتحت اللينك لو صفحة اعادة التعيين فيها اي روابط لمواقع خارجية هيتم تسريب ال token في ال referer header لو ضغط علي اي رابط

3- التطبيق مش بيتاكد من صلاحية الtoken

+ بالنسبة للوقت : لو التطبيق مش بيتأكد من وقت ال token بالتالي هيفضل صالح للاستخدام لفترة طويلة

+ بالنسبة للمستخدم: لو التطبيق مش بيتأكد من ان الtoken خاص بالمستخدم ولا لا بالتالي يقدر اي حد يستخدم ال token الخاص بيه في اعادة تعيين كلمة المرور لمستخدم تاني

4- التطبيق مش بيتأكد من صحة البيانات اللي في ال token في حالة لو كان بيعتمد علي ال JWT مثلا

في حالة لو بنستخدم ال JWT بالتالي كل البيانات المستخدمة في عملية اعادة تعيين كلمة المرور زي ال user id وال random token وال expiry time في الtoken, بالتالي لو التطبيق مش بيتأكد من صحة ال token المستخدم يقدر يعدل الtoken ويعمل اعادة تعيين لكلمة المرور لحساب مستخدم تاني

5- التطبيق بيعتمد علي ال Host Header في انو يعمل generate لل password reset token URL

لو افترضنا ان في server عنوانه 1.1.1.1 عليه اكتر من موقع ازاي هقدر اعرف ال server ايه الموقع اللي انا عايز اتصفحه؟ السر في ال host header دي اللي بتعرف ال server ايه هو الموقع المطلوب

لو التطبيق بيعتمد علي ال host header في انو ي generate ال URL بقا في خطورة هنا لان المستخدم هو المتحكم في الطلب فلو attacker بعد طلب اعادة تعيين كلمة المرور وخلي قيمة ال host header تبقي domain تاني تحت سيطرة ال attacker (هجوم ال host header injection) الرابط هيروح للمستخدم علي الايميل ولاكن الدومين مختلف بالتالي لو المستخدم ضغط علي اللينك ال token هيتبعت لل attacker مش للدومين الاصلي

https://evil.com/password_rest?token=<token>

6- ال URL scheme تكون HTTP

لو URL scheme الخاصة بالرابط اللي التطبيق بعته HTTP مش HTTPS كدا لو المستخدم ضغط علي اللينك الtoken هيتبعت في اتصال غير مشفر بالتالي لو في attacker بيعترض الاتصال بقا قادر انو يعرف الtoken

الحلول لاستخدام URL Tokens بشكل اَمن

1- الtokens تكون عشوائية ومرتبطه بال user ID في قاعدة البيانات

2- لو هتستخدم tokens زي JWT تأكد من استخدامها بشكل صحيح لتجنب عملية التلاعب في البيانات من قبل المستخدم

3- ال Domain المستخدم في عملية ال generation لل URL Token يكون Hard-coded بدل الاعتماد علي ال Host header

4- تاكد من ان URL scheme تكون HTTPS

5- حذف ال token من قاعدة البيانات بعد استخدامة

6- تحديد زمن صلاحية لل token

7- تأكد من ازالة اي روابط لمواقع خارجية من صفحة اعادة تعيين كلمة المرور او استخدم ال Refferer-policy وخلي القيمة بتاعتها norefferer

المصادر

Last updated