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

المصدر: http://portswigger.net/web-security/csrf

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

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

ما هو الـ CSRF ؟

يعتبر تزوير CSRF ثغرة أمنية على الويب تتيح للمهاجم أن يدفع المستخدمين للقيام بأفعال من دون أن يقصدوا إجراءها فعلياً. و هي تتيح للمهاجم أن يتفادى، بشكل جزئي، سياسة نفس الاصل (same origin policy) المصممة لمنع المواقع المختلفة من التداخل فيما بينها.

ما هو تأثير هجوم الـ CSRF ؟

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

كيف يعمل الـ CSRF ؟

لكي يكون هجوم CSRF ممكناً، يجب توفر ثلاثة شروط أساسية:

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

  • ان تعتمد جلسة الاتصال (session) على ملفات تعريف الارتباط (Cookies). يتطلب تنفيذ الإجراء إصدار طلب (request HTTP) واحد أو أكثر ، و يجب أن يعتمد التطبيق فقط على ملفات تعريف الارتباط (cookies) لتحديد المستخدم الذي قدم الطلبات. و أن لا توجد أية آلية أخرى لتتبع الsessions أو للتحقق من صحة طلبات المستخدم.

  • ان لا يوجد في الطلب (request) عامل متغير (parameter) لا يمكن للمهاجم التنبؤ به. يجب ألا تحتوي الطلبات (requests) التي تنفذ الإجراء على أي عامل متغير (parameter) لا يمكن للمهاجم تحديدها أو تخمين قيمهما. على سبيل المثال، عند جعل أحد المستخدمين يقوم بتغيير كلمة المرور الخاصة به، تكون هذه الوظيفة امنة إذا احتاج المهاجم إلى معرفة قيمة كلمة المرور الحالية.

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

    POST /email/change HTTP/1.1
    Host: vulnerable-website.com
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 30
    Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE

    email=wiener@normal-user.com

هذا يفي بالشروط المطلوبة لـ CSRF:

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

  • يستخدم التطبيق ملف تعريف ارتباط للجلسة (cookies) لتحديد المستخدم الذي أصدر الطلب. و لا توجد أية رموز (tokens) أو آليات أخرى لتتبع جلسات عمل المستخدم (sessions).

  • يمكن للمهاجم تحديد قيم الparameters ضمن الطلب. اللازمة لتنفيذ الإجراء بسهولة.

مع توفر هذه الشروط، يمكن للمهاجم إنشاء صفحة ويب تحتوي على كود HTML التالي:

<html>
  <body>
    <form action="https://vulnerable-website.com/email/change" method="POST">
      <input type="hidden" name="email" value="pwned@evil-user.net" />
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html> 

إذا قام المستخدم الضحية بزيارة صفحة المهاجم على الويب، فسيحدث ما يلي:

  • ستقوم صفحة المهاجم بإرسال طلب (HTTP request) إلى موقع الويب المعرض للثغرة.

  • إذا كان المستخدم قد سجل دخوله إلى الموقع المستهدف فسيقوم المتصفح بتضمين بيانات تعريف الارتباط cookie للجلسة session الخاصة بالمستخدم ضمن الطلب تلقائياً (بافتراض عدم استخدام خاصية SameSite)

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

ملاحظة :

على الرغم من أن CSRF عادةً ما تكون مقترنة بsessions المعتمدة على cookies، إلا أنها يمكن أن تظهر في سياقات أخرى عندما يضيف التطبيق تلقائياً بعض البيانات الأمنية الخاصة بالمستخدم إلى الطلبات requests ، مثل المصادقة بواسطة الHTTP (HTTP Basic authentication) و المصادقة المعتمدة على الشهادات (certificate-based authentication).

كيفية إنشاء هجوم CSRF

إن إنشاء ملف ال HTML المطلوب لاستغلال ثغرة CSRF بشكل يدوي يمكن أن يكون أمراً مرهقاً، خاصةً عندما يحتوي الطلب (request) المستهدف على عدد كبير من parameters، أو عندما يكون هناك اختلافات أخرى في الطلب. و أسهل طريقة لإنشاء CSRF هي استخدام generator CSRF PoC المدمج في Burp Suite Professional كما يلي:

  • حدد الطلب request في أي مكان في Burp Suite Professional الذي تريد اختباره أو استغلاله.
  • انقر بالزر الأيمن ثم من القائمة المسدلة اختر : Engagement tools / Generate CSRF PoC.
  • سيقوم Burp Suite بإنشاء بعض أكواد HTML التي ستقوم بتشغيل الطلب المحدد (بدون ملفات cookies، والتي ستتم إضافتها تلقائياً من خلال متصفح الضحية).
  • هناك العديد من الخيارات التي يمكنك تعديلها في CSRf PoC generator لتحسن بعض نواحي الهجوم، و قد تحتاج إلى القيام بذلك في بعض المواقف غير المعتادة للتعامل مع الخصائص المختلفة للطلبات (requests).
  • انسخ كود HTML الذي تم إنشاؤه في صفحة ويب، و افتحه من خلال متصفح تم تسجيل الدخول بواسطته إلى موقع الويب المستهدف، و اختبر ما إذا كان الطلب (requests) المقصود قد تم تحريره و إرساله بنجاح و أن الإجراء المطلوب قد تحقق .

كيف يتم إرسال الاستغلال لثغرة الـ CSRF

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

و من الجدير بالذكر أن بعض عمليات استغلال CSRF البسيطة تستخدم طريقة GET و يمكن أن يتم تضمينها بعنوان URL وحيد على موقع الويب المستهدف. و في هذه الحالة، فقد لا يحتاج المهاجم إلى استخدام موقع خارجي، و يمكنه ارسال الضحايا مباشرةً عنوان URL ضار على النطاق (domain) المستهدف. ففي المثال السابق، إذا كان من الممكن تنفيذ طلب تغيير عنوان البريد الإلكتروني باستخدام طريقة GET، فسيكون الهجوم المتضمن ذاتياً كما يلي:

<img src="https://vulnerable-website.com/email/change?email=pwned@evil-user.net">

منع هجمات CSRF

إن أقوى أسلوب للدفاع ضد هجمات CSRF يكون من خلال تضمين رمز (CSRF token) ضمن الطلبات (request) ذات الصلة. و يجب أن يكون الرمز (token) :

  • غير قابل للتنبؤ مع عشوائية (entropy) عالية ، كما هو الحال في session tokens عامةً.
  • مرتبط بجلسة المستخدم (session).
  • يتم التحقق منه بدقة في كل مرحلة قبل تنفيذ الإجراء المتعلق بذلك الطلب .

هناك إجراء دفاعي إضافي فعال جزئياً ضد الـ CSRF، و يمكن استخدامه مع الـ tokens CSRF ، هو خاصية SameSite للـ cookies (ملفات تعريف الارتباط) .

ثغرات CSRF الشائعة

تنشأ ثغرات CSRF الأكثر إثارة للاهتمام نتيجة الأخطاء في التحقق من صحة ال tokens CSRF.

ففي المثال السابق، بفرض أن التطبيق يحتوي الآن على رمز (CSRF token) ضمن الطلب (request) الخاص بتغيير كلمة مرور المستخدم:

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm

csrf=WfF1szMUHhiokx9AHFply5L2xAOfjRkE&email=wiener@normal-user.com

هذا يجب أن يمنع هجمات CSRF لأنه يخالف الشروط اللازمة لثغرة CSRF: فالتطبيق لم يعد يعتمد فقط على ملفات تعريف الارتباط cookies للتعامل مع الجلسة، كما يحتوي الطلب على عامل متغير (parameter) لا يمكن للمهاجم تحديد قيمته. و مع ذلك، فهناك عدة طرق يمكن من خلالها كسر هذا الدفاع ، مما يعني أن التطبيق لا يزال عرضة للـ CSRF.

التحقق من صحة رمز CSRF يعتمد على طريقة الطلب

تقوم بعض التطبيقات بالتحقق من صحة الرمز (token) عندما يستخدم الطلب الطريقة POST لكنها تتجاوز عملية التحقق عند استخدام طريقة GET.

و في هذه الحالة، يمكن أن ينتقل المهاجم لاستخدام طريقة GET لتجاوز التحقق من الصحة و إرسال هجوم CSRF:

GET /email/change?email=pwned@evil-user.net HTTP/1.1
Host: vulnerable-website.com
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm

التحقق من صحة رمز CSRF يعتمد على الرمز ( token ) المعطى

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

في هذه الحالة، يمكن للمهاجم إزالة العامل المتغير (parameter) الذي يحتوي على الرمز token بالكامل (و ليس قيمته فقط) لتجاوز التحقق من الصحة و إرسال هجوم CSRF:

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm

email=pwned@evil-user.net

رمز CSRF غير مرتبط بجلسة المستخدم ( (user session

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

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

رمز CSRF مرتبط بملف تعريف ارتباط cookie غير متعلق بال session

في بعض الحالات الأخرى للثغرة السابقة، تقوم بعض التطبيقات بربط رمز CSRF بملف تعريف ارتباط (cookie)، و لكن ليس بنفس ملف تعريف الارتباط (cookie) الذي يتم استخدامه لتتبع ال session. يمكن أن يحدث هذا بسهولة عندما يستخدم تطبيق ما إطارين (frameworks) مختلفين، أحدهما للتعامل مع الجلسة و الآخر لحماية CSRF، دون أن يتم دمجهما معاً :

 POST /email/change HTTP/1.1
 Host: vulnerable-website.com
 Content-Type: application/x-www-form-urlencoded
 Content-Length: 68
Cookie: session=pSJYSScWKpmC60LpFOAHKixuFuM4uXWF; csrfKey=rZHCnSzEp8dbI6atzagGoSYyqJqTz5dv

 csrf=RhV7yQDO0xcq9gLEah2WVbmuFqyOq7tY&email=wiener@normal-user.com

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

ملاحظة :

لا يشترط أن يكون السلوك الذي يسمح بوضع ملفات تعريف الارتباط (cookie) موجوداً ضمن تطبيق الويب نفسه الذي توجد فيه ثغرة CSRF. حيث أن أي تطبيق آخر ضمن نفس نطاق DNS العام يُحتَمَل أن تتم الاستفادة منه في تعيين ملفات تعريف الارتباط (cookie) في التطبيق المستهدف، إذا كان لملف تعريف الارتباط (cookie) الذي يتم التحكم فيه مجال (scope) مناسب. على سبيل المثال ، يمكن الاستفادة من إجراء إضافة الcookie الموجود في staging.demo.normal-website.com لوضع ملف تعريف الارتباط الذي سيتم إرساله إلى secure.normal-website.com.

تكرار رمز CSRF ببساطة في ملف تعريف الارتباط

في تنويع آخر للثغرة السابقة، لا تحتفظ بعض التطبيقات بأي سجل (record) على الخادم للرموز tokens التي تم إصدارها. و بدلاً من ذلك تقوم بتكرار كل رمز token ضمن ملف تعريف ارتباط (cookie) و العامل المتغير (parameter) ضمن الطلب request. و فيما بعد، عند التحقق من صحة الطلب، يقوم التطبيق ببساطة بالتحقق من أن الرمز المميز المقدم كعامل متغير (parameter) ضمن الطلب يطابق القيمة المقدمة في ملف تعريف الارتباط. يُدعى ذلك أحياناً دفاع “الإرسال المزدوج” ضد الـ CSRF، و يتم تأييده نظراً لسهولة تنفيذه و كونه لا يتطلب أية حالة (state) على الخادم:

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: session=1DQGdzYbOJQzLP7460tfyiv3do7MjyPw; csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa
csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa&email=wiener@normal-user.com

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

الدفاعات المستندة إلى المحيل ( Referer ) ضد الـ CSRF

بصرف النظر عن الدفاعات التي تستخدم رموز(tokens) CSRF ، تستخدم بعض التطبيقات HTTP Referer header (خاصية المُحيل referrer التي يتم وضعها ضمن الheader الخاص بطلب الHTTP) لمحاولة الدفاع ضد هجمات CSRF، و يتم ذلك عادة من خلال التحقق من أن الطلب تم إنشاؤه من ضمن النطاق domain الخاص بالتطبيق. هذا الأسلوب عموما أقل فعالية وغالباً ما يتم تجاوزه.

ترويسة (خاصية في ال header الخاص بطلب ال HTTP ( Referer :

ترويسة المُحيل Referer في الHTTP (والتي تمت كتابتها بشكل خاطىء إملائياً عن غير قصد في مواصفات الـ HTTP) هي عبارة عن ترويسة اختيارية تحتوي على عنوان URL لصفحة الويب المرتبطة بالمصدر resource المطلوب. عادةً ما يتم إضافتها تلقائياً من قبل المتصفحات عندما يقوم المستخدم بإرسال طلب HTTP، بما في ذلك عند النقر على رابط ما أو إرسال نموذج (form). هناك العديد من الطرق التي تسمح للصفحة المحيلة بحجب أو تعديل قيمة ترويسة المحيل (Referer header). و غالباً ما يتم ذلك لأسباب تتعلق بالخصوصية.

التحقق من صحة المُحيل يتعلق بالترويسة ( header ) المقدمة

تقوم بعض التطبيقات بالتحقق من صحة ترويسة المحيل Referer header عندما تكون موجودةً في الطلبات requests و لكنها تتخطى عملية التحقق إذا تم إغفال تلك الترويسة.

في هذه الحالة، يمكن للمهاجم صياغة استغلال CSRF الخاص به بحيث يجعل متصفح المستخدم الضحية يقوم بإسقاط ترويسة المحيل (Referer header) في الطلب الناتج. هناك عدة طرق لتحقيق ذلك، و لكن أسهلها استخدام وسم (tag) الـ META ضمن صفحة الـ HTML التي تستضيف هجوم الـ CSRF :

التحقق من صحة المحيل Referer يمكن التحايل عليه

تقوم بعض التطبيقات بالتحقق من صحة ترويسة المحيل (Referer header) بطريقة ساذجة يمكن تجاوزها. على سبيل المثال، إذا كان التطبيق يقوم بالتحقق فقط من كون المحيل Referer يحتوي على النطاق domain الخاص به، فعندها يمكن للمهاجم وضع القيمة المطلوبة في مكان آخر ضمن عنوان الـ URL:

http://attacker-website.com/csrf-attack?vulnerable-website.com

إذا تحقق التطبيق من أن النطاق domain الموجود في المحيل Referer يبدأ بالقيمة المُفتَرَضَة، فيمكن للمهاجم وضع هذا كنطاق فرعي subdomain للنطاق الخاص به:

http://vulnerable-website.com.attacker-website.com/csrf-attack