javascript لماذا جوجل prepend بينما(1) ؛ على ردودهم JSON؟




ajax security (4)

قد يكون ذلك من الصعب على جهة خارجية إدراج استجابة JSON في مستند HTML بعلامة <script> . تذكر أن علامة <script> معفية من سياسة المنشأ الأصلية .

https://code.i-harness.com

لماذا جوجل prepend while(1); على ردودهم (الخاصة) JSON؟

على سبيل المثال ، إليك استجابة أثناء تشغيل التقويم وإيقافه في تقويم Google :

while(1);[['u',[['smsSentFlag','false'],['hideInvitations','false'],
  ['remindOnRespondedEventsOnly','true'],
  ['hideInvitations_remindOnRespondedEventsOnly','false_true'],
  ['Calendar ID stripped for privacy','false'],['smsVerifiedFlag','true']]]]

أفترض أن هذا لمنع الناس من القيام eval() ، ولكن كل ما عليك فعله فعلاً هو استبدال while ثم تعيينك. أفترض أن منع eval هو التأكد من أن الناس يكتبون كود JSON الآمن للتحليل.

لقد رأيت ذلك مستخدمًا في مكانين آخرين ، أيضًا ، ولكن أكثر من ذلك بكثير مع Google (البريد والتقويم وجهات الاتصال ، وما إلى ذلك) الغريب في الأمر ، يبدأ محرّر مستندات Google بـ &&&START&&& بدلاً من ذلك ، ويبدو أن جهات اتصال Google تبدأ بـ while(1); &&&START&&& while(1); &&&START&&& .

ماذا يجري هنا؟


نظرًا لأن العلامة <script> معفاة من "سياسة الأصل نفسه" التي تعد ضرورة أمنية في عالم الويب ، while(1) عند إضافتها إلى استجابة JSON تمنع إساءة استخدامها في العلامة <script> .


يمنع JSON hijacking ، وهي مشكلة أمان JSON رئيسية تم حلها رسميًا في جميع المتصفحات الرئيسية منذ عام 2011 باستخدام ECMAScript 5.

مثال مفترض: قل أن Google لديه عنوان URL مثل mail.google.com/json?action=inbox والذي يعرض أول 50 رسالة من صندوق الوارد الخاص بك بتنسيق JSON. لا يمكن لمواقع الويب الشر على النطاقات الأخرى تقديم طلبات AJAX للحصول على هذه البيانات بسبب سياسة الأصل نفسه ، لكن يمكنها تضمين عنوان URL عبر علامة <script> . يتم زيارة عنوان URL مع ملفات تعريف الارتباط الخاصة بك ، وبإلغاء طرق إنشاء مُنشئ الصفيف العام أو ملحقاته ، يمكن أن يكون لديهم طريقة تسمى كلما تم تعيين سمة كائن (صفيف أو تجزئة) ، مما يسمح لهم بقراءة محتوى JSON.

في while(1); أو &&&BLAH&&& يمنع هذا: &&&BLAH&&& طلب AJAX على mail.google.com بالوصول الكامل إلى المحتوى النصي ، ويمكنه تجريده بعيدًا. لكن إدراج علامة <script> ينفذ JavaScript بشكل عمياء دون أي معالجة ، مما ينتج عنه حلقة لا نهائية أو خطأ في بناء الجملة.

هذا لا يعالج مشكلة تزوير طلب المواقع المشتركة .


يمنع الكشف عن الرد من خلال اختطاف JSON.

من الناحية النظرية ، فإن محتوى ردود HTTP محمي بواسطة سياسة المنشأ الأصلية: لا يمكن لصفحات من مجال الحصول على أي أجزاء من المعلومات من الصفحات على المجال الآخر (ما لم يسمح بذلك صراحة).

يمكن للمهاجم طلب صفحات على مجالات أخرى نيابة عنك ، على سبيل المثال باستخدام علامة <script src=...> أو <img> ، لكنه لا يمكنه الحصول على أي معلومات حول النتيجة (الرؤوس ، المحتويات).

وبالتالي ، إذا قمت بزيارة صفحة أحد المهاجمين ، فلن تتمكن من قراءة بريدك الإلكتروني من gmail.com.

إلا أنه عند استخدام علامة البرنامج النصي لطلب محتوى JSON ، يتم تنفيذ JSON كـ Javascript في بيئة مسيطر عليها للمهاجمين. إذا كان بإمكان المهاجم استبدال مُنشئ Array أو Object أو أي طريقة أخرى مستخدمة أثناء بناء الكائن ، فإن أي شيء في JSON يمر عبر رمز المهاجم ، وسيتم الكشف عنه.

لاحظ أن هذا يحدث في الوقت الذي يتم فيه تنفيذ JSON كـ Javascript ، وليس في الوقت الذي يتم فيه تحليله.

هناك العديد من الإجراءات المضادة:

التأكد من عدم تنفيذ JSON أبدًا

عن طريق وضع فترة while(1); قبل بيانات JSON ، تتأكد Google من عدم تنفيذ بيانات JSON على أنها Javascript.

فقط صفحة شرعية يمكنها فعلاً الحصول على المحتوى بالكامل ، تجريد while(1); ، وتحليل الباقي مثل JSON.

أشياء مثل for(;;); وقد شوهد في الفيسبوك على سبيل المثال ، مع نفس النتائج.

التأكد من أن JSON غير صالح Javascript

وبالمثل ، فإن إضافة رموز غير صالحة قبل JSON ، مثل &&&START&&& ، تتأكد من عدم تنفيذها مطلقًا.

دائما العودة JSON مع كائن من الخارج

هذه طريقة مستحسنة لـ OWASP للحماية من اختطاف JSON وهي الأقل تدخلاً.

على نحو مشابه للتدابير المضادة السابقة ، فإنه يتأكد من عدم تنفيذ JSON على أنها Javascript.

كائن JSON صالح ، عندما لا يكون محاطًا بأي شيء ، غير صالح في Javascript:

eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :

هذا صحيح JSON:

JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}

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

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

مقارنة بين الأساليب المذكورة أعلاه

طريقة OWASP أقل تدخلاً ، حيث إنها لا تحتاج إلى أي تغييرات في مكتبة العميل ، وتنقل JSON صالح. ليس من المؤكد ما إذا كانت أخطاء المتصفح السابقة أو المستقبلية قد تهزم هذا الأمر. كما لاحظoriadam ، من غير الواضح ما إذا كان يمكن تسريب البيانات في خطأ تحليل من خلال معالجة خطأ أم لا (مثل window.onerror).

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

تتطلب كلتا الطريقتين تغييرات من جانب الخادم من أجل تجنب المطورين من إرسال JSON الضعيف عن طريق الخطأ.





security