حين شرعنا في بناء ProxyOrb، واجهنا مفارقة جوهرية في كل قرار تصميمي: خادم البروكسي يعمل أساساً عبر إيهام المتصفح بأن محتوى الطرف الثالث ينتمي إلى المصدر نفسه. وهذا بطبيعته يعني التحايل على النموذج الأمني الأساسي للمتصفح. غير أن المتصفحات الحديثة أمضت خمسة عشر عاماً في تراكم دفاعات متطورة ومتصاعدة لمواجهة هذا النوع من الالتباس في المصادر.
تتناول هذه المقالة هذا التوتر من مبادئه الأولى. إن كنت باحثاً في أمان الويب، أو مختبر اختراق، أو مهندساً متخصصاً في أمان المتصفحات، وتريد أن تفهم كيف تتفاعل خوادم البروكسي فعلياً مع سياسة نفس المصدر — لا على مستوى المفاهيم، بل على مستوى ترويسات HTTP، وكود Chromium المصدري، وصفقات الهندسة في بيئات الإنتاج — فهذا المقال لك.
سنتناول الأساس النظري لـ SOP، وإعادة كتابة URL، وCORS، وCORB/CORP، وCOEP/COOP، وService Workers، وiframes، والتداعيات الأمنية على مشغّلي البروكسي ومستخدميه.
1. الأساس النظري لسياسة نفس المصدر
سياسة نفس المصدر (SOP) تُعرَّف بثلاثة عناصر: المخطط (scheme) + المضيف (host) + المنفذ (port). لا يُعدّ عنوانان من المصدر ذاته إلا إذا تطابقت هذه العناصر الثلاثة تماماً. https://example.com:443 وhttp://example.com:80 مصدران مختلفان رغم أنهما يشيران إلى الخادم نفسه.
ما يُساء فهمه في الغالب هو ما تمنعه SOP فعلاً مقابل ما تسمح به. SOP لا تحجب:
- تحميل الصور (
<img src>) من مصادر أخرى - تحميل السكريبتات (
<script src>) من مصادر أخرى - تحميل صفحات الأنماط (
<link rel="stylesheet">) من مصادر أخرى - تضمين iframes من مصادر أخرى (وإن كانت محتويات المستند المُضمَّن معزولة)
- إرسال نماذج HTML (
<form action>) إلى مصادر أخرى
ما تمنعه SOP فعلاً هو قراءة الاستجابة للطلبات المُرسَلة عبر fetch() أو XMLHttpRequest من مصادر مختلفة. الطلب يُرسَل فعلاً وتتم رحلة الشبكة، لكن جسم الاستجابة وترويساتها تُحجَب عن كود JavaScript الذي يعمل في مصدر مختلف.
هذا التمييز بالغ الأهمية لخوادم البروكسي. مهمة البروكسي الكاملة هي دمج مصدرين (خادم البروكسي والخادم المستهدف) في مصدر واحد، للتخلص من حاجز المصادر المختلفة. فمتى بدت جميع الموارد وكأنها قادمة من https://proxyorb.com، فإن قيود SOP المتعلقة بـ قراءة الاستجابات لا تُطبَّق أصلاً.
"الفضاء المشروع" الذي تستثمره خوادم البروكسي هو إعادة كتابة URL: بدلاً من https://example.com/api/data، يصبح كل طلب https://proxyorb.com/api/data?__pot=aHR0cHM6Ly9leGFtcGxlLmNvbQ==. من منظور المتصفح، هذا طلب من المصدر نفسه. لم يُتحايَل على SOP — بل أصبح غير ذي صلة لأن المصدر الظاهر لكل المحتوى قد تغيّر.
2. معمارية إعادة كتابة URL في ProxyOrb
لفهم التداعيات الأمنية، لا بد من فهم آلية الترميز. يستخدم ProxyOrb معامل URL يُسمى __pot (رمز أصل البروكسي - proxy origin token) الذي يحمل المصدر المستهدف بترميز Base64.
معامل __pot
يُرمِّز المعامل __pot دائماً المصدر فحسب (المخطط + المضيف، دون المسار)، لا URL الكامل. يعني هذا أن https://example.com/some/deep/path?foo=bar وhttps://example.com/other/page كلاهما يُنتجان قيمة __pot ذاتها: aHR0cHM6Ly9leGFtcGxlLmNvbQ== (وهي ترميز Base64 لـ https://example.com). أما المسار الفعلي وسلسلة الاستعلام فتُحفَظان كما هي في مسار URL الخاص بالبروكسي وسلسلة استعلامه.
حين يتصفح مستخدم https://proxyorb.com/?__pot=aHR0cHM6Ly9leGFtcGxlLmNvbQ==، تفكّ البوابة الترميزَ وتُعيد بناء URL الأصلي:
ثم تُعيد البوابة توجيه الطلب إلى الخادم المستهدف الفعلي، مُعيدةً كتابة ترويسة Origin ليرى الخادم الأصلي نطاقه بدلاً من نطاق البروكسي:
إعادة كتابة URL من جانب العميل عبر Service Worker
تتولى البوابة الجانبَ الخادمي. أما الجانب العميلي — إعادة كتابة URLs في استجابات HTML وJavaScript وCSS بحيث تستمر جميع الطلبات الفرعية عبر البروكسي — فيتولاه Service Worker.
التحويل الأساسي يُحوِّل أي URL يظهر في محتوى الصفحة إلى صيغة البروكسي:
فمثلاً، https://cdn.example.com/bundle.js المُشار إليه داخل صفحة يجري عرضها عبر البروكسي يصبح https://proxyorb.com/bundle.js?__pot=aHR0cHM6Ly9jZG4uZXhhbXBsZS5jb20=.
هذه إعادة الكتابة شاملة: تغطي fetch() وXMLHttpRequest و<script src> و<img src> واتصالات WebSocket وعلامات <link>. حين يشير كل URL في الصفحة إلى مصدر البروكسي، لا يُرسِل المتصفح أي طلب من مصدر مختلف — كل طلب هو من نفس المصدر بحكم البنية.
استعادة __pot دون تصفح كامل
حالة حافّية دقيقة تنشأ مع الطلبات الصادرة من داخل صفحة مُبرمَجة عبر البروكسي لكنها تفتقر إلى معامل __pot — كـfetch('/api/data') النسبي الذي يُطلَق قبل إعادة كتابة URL من قِبَل Service Worker، أو طلب صادر من سكريبت مُحقَن ديناميكياً تجاوز معيد الكتابة.
يحلّ Service Worker الرمز المفقود عبر بحث متتالٍ:
للبوابة مسار استعادة موازٍ: إذا وصل طلب دون __pot لكن يحمل ترويسة Referer تشير إلى URL من المصدر نفسه يتضمن __pot، تستخرج البوابة الرمز من المُحيل وتُلحقه بالطلب الحالي. هذا يُعالج سيناريوهات التصفح التي تُجرَّد فيها الرمز بواسطة JavaScript الخاصة بالصفحة قبل وصول الطلب إلى البوابة.
3. CORS: نظام الإذن الصريح للمصادر المختلفة
صُمِّم CORS (مشاركة الموارد عبر المصادر - Cross-Origin Resource Sharing) ليسمح للخوادم بالموافقة صراحةً على الوصول من مصادر مختلفة عبر إرسال ترويسات استجابة محددة. من منظور البروكسي، يُفرز CORS مشكلتين متمايزتين.
المشكلة الأولى: اعتراض طلبات CORS المبدئية (Preflight)
حين يُرسِل كود JavaScript داخل صفحة طلب fetch() بترويسات غير بسيطة (كـAuthorization أو Content-Type: application/json)، يُرسِل المتصفح أولاً طلب OPTIONS مبدئياً. إن لم تتضمن استجابة الخادم المستهدف لهذا الطلب ترويسات CORS متساهلة، يُحجَب الطلب الفعلي.
في معمارية ProxyOrb، يعترض Service Worker جميع طلبات OPTIONS ويُجيب عليها اصطناعياً — قبل أن تصل إلى البوابة أصلاً — مُعيداً استجابةً تُفسح المجال للطلب الفعلي:
على مستوى البوابة، تحصل كل استجابة مُبرمَجة عبر البروكسي على ترويسات CORS مكافئة:
المشكلة الثانية: الطلبات بالبيانات الاعتمادية (Credentialed Requests)
مجموعة Access-Control-Allow-Credentials: true مع Access-Control-Allow-Origin بقيمة غير wildcard أمر بالغ الأهمية. يشترط CORS قيمة مصدر صريحة (لا *) كلما أُدرِجت البيانات الاعتمادية. يُصدِر Service Worker جميع الطلبات الصادرة بـcredentials: 'include'، لذا يجب على البوابة أن تُعيد إرسال المصدر الطالب الدقيق بدلاً من wildcard.
يعني هذا أن جميع ملفات تعريف الارتباط (cookies) المخزَّنة تحت proxyorb.com — المتراكمة من كل موقع مستهدف زاره المستخدم عبر البروكسي — تُرسَل مع كل طلب مُبرمَج. هذا مقصود (يحافظ على حالة الجلسة للمواقع التي سجّل فيها المستخدم دخوله)، لكنه أيضاً اعتبار أمني مهم نناقشه في القسم الثامن.
نمط شَطب ترويسات CORS واستبدالها
قد تحمل استجابة مُبرمَجة ترويسات CORS من الخادم المستهدف غير صحيحة من منظور المتصفح (إذ تُشير إلى مصدر الهدف لا مصدر البروكسي). يشطبها Service Worker ويستبدلها:
4. CORB وCORP: دفاعات Chromium الأشد صرامة
يعتمد CORS على الموافقة الصريحة من الخوادم. أضاف Chromium آليتين تعملان افتراضياً، بصرف النظر عن إعدادات CORS.
حجب القراءة من المصادر المختلفة (CORB)
أُطلِق CORB في Chrome 67 (2018) كجزء من تخفيفات Spectre. الفكرة الجوهرية: حتى لو لم تُقرأ استجابة من مصدر مختلف في جسمها بواسطة JavaScript، فمجرد جلبها وفك ترميزها في عملية العرض يعني أنها موجودة في مساحة عنوان تلك العملية. يمكن لهجمات Spectre بعد ذلك استخراجها عبر قنوات جانبية.
يمنع CORB بعض الاستجابات من المصادر المختلفة من الدخول إلى عملية العرض أصلاً. تحديداً، حين يجلب وسم <script> أو <img> استجابة من مصدر مختلف وكان نوع محتواها text/html أو text/xml أو application/json، يفحص Chromium الجسم (باستخدام متشمم MIME-type محدد في مواصفة CORB) ويستبدل الاستجابة باستجابة فارغة قبل أن تراها عملية العرض.
لخادم بروكسي، سيكون CORB كارثياً لو كانت الطلبات من مصادر مختلفة فعلاً. نقطة نهاية API تُعيد application/json مُجلوبة من وسم <script> ستُعيد فراغاً صامتاً. غير أن ProxyOrb يُعيد كتابة جميع URLs لتكون من المصدر نفسه، فشرط المصدر المختلف في CORB لا يُستثار قط — المتصفح لا يرى أبداً استجابة JSON من مصدر مختلف، لأن كل الاستجابات من منظوره تأتي من proxyorb.com.
الحالة الوحيدة التي يهم فيها CORB هي خلال فترة الانتقال قبل تسجيل Service Worker الكامل واعتراضه للطلبات. إن نجا أي طلب من إعادة الكتابة خلال تلك النافذة، قد يحجبه CORB. هذه الحالة الاستباقية هي السبب في أن ProxyOrb يحتفظ أيضاً بطبقة معترض على الخيط الرئيسي تُرقّع XMLHttpRequest وfetch ومحدِّدات سمات DOM بشكل متزامن قبل تشغيل أي JavaScript للصفحة — مُوفِّرةً احتياطياً خلال بدء تشغيل Service Worker.
تجدر الإشارة إلى أن CORB قد حلّ جزئياً محله Opaque Response Blocking (ORB)، الذي يجري Chromium اعتماده حالياً. يُنقّح ORB قواعد CORB لتقليل الإيجابيات الزائفة مع الحفاظ على حمايات Spectre. التداعيات على توافق البروكسي مشابهة.
سياسة موارد المصادر المختلفة (CORP)
يسمح CORP، المُعرَّف في مواصفة Fetch، للخوادم بأن تُعلن أن مواردها لا يجب تحميلها إلا من سياقات المصدر نفسه أو الموقع نفسه:
حين يصادف Chromium هذه الترويسة في طلب موارد فرعية من مصدر مختلف، يحجب الاستجابة كلياً. هذا أشد قسوة من CORB — يُطبَّق بصرف النظر عن نوع المحتوى ولا يمكن التحايل عليه عبر تشمم MIME.
مجدداً، نظراً لأن إعادة كتابة URL في ProxyOrb تجعل جميع الطلبات من المصدر نفسه من منظور المتصفح، لا تُستثار ترويسات CORP من الخوادم المستهدفة لحجب الطلبات. وتشطب البوابة أيضاً هذه الترويسات من الاستجابات بشكل دفاعي، مُعالِجةً أي حالات حافّة حين ينزلق طلب ما دون إعادة كتابة URL.
المشكلة الأعمق مع CORP هي في الواقع حالة تُساعد فيها معمارية البروكسي على التوافق: لو كانت https://api.example.com وhttps://www.example.com كلتاهما تُبرمَجان عبر البروكسي، فكلتاهما تُعيَّن إلى مصدر البروكسي ذاته، فيصبح الجلب من إحداهما إلى الأخرى من المصدر نفسه فعلاً — قيود CORP لم تعد تُطبَّق بينهما.
5. COEP وCOOP: عزل المشترك في المصدر (Cross-Origin Isolation)
منذ Chrome 92 (2021)، قُيِّد الوصول إلى SharedArrayBuffer — وبالتبعية المؤقتات عالية الدقة المُستخدَمة في بعض واجهات API للأداء — بالصفحات التي تختار عزل المشترك في المصدر. يستلزم هذا الاختيار عمل ترويستَي استجابة معاً بتناسق.
سياسة تضمين المصادر المختلفة (COEP)
حين تُرسِل صفحة هذه الترويسة، يُلزِم المتصفح أن كل مورد فرعي تُحمِّله تلك الصفحة إما:
- من المصدر نفسه، أو
- يُرسِل
Cross-Origin-Resource-Policy: cross-originصراحةً، أو - له استجابة CORS متساهلة للجلب باعتمادات
المشكلة لخوادم البروكسي: إذا أرسل موقع مستهدف COEP: require-corp على مستنده الرئيسي، وقُدِّم ذلك المستند عبر البروكسي مع الحفاظ على الترويسة، يطلب المتصفح الآن من كل مورد فرعي تُحمِّله الصفحة أيضاً أن يشارك. أي مورد لا يفعل — وأغلبها لن يفعل — يُسبِّب خطأ في الشبكة.
سياسة فتح المصادر المختلفة (COOP)
يتحكم COOP فيما إذا كانت الصفحة يمكنها مشاركة مجموعة سياق التصفح مع صفحات من مصادر مختلفة. حين تُضبَط على same-origin، تفتح ملاحة من مصدر مختلف مجموعة سياق تصفح جديدة، كاسرةً مراجع window.opener وقنوات postMessage بين الصفحة وأي مفتوحين من مصادر مختلفة.
بالنسبة للبروكسي، COOP أقل تدميرية فوريةً من COEP، لكنها تُعطِّل مواقع تعتمد على تدفقات postMessage من مصادر مختلفة (وأشيع مثال تدفقات النوافذ المنبثقة لـ OAuth).
معضلة مشغّل البروكسي
هذه هي أصعب مفاضلة نواجهها في ProxyOrb:
الخيار أ: شطب COEP وCOOP من الاستجابات.
- إيجابية: تحميل الموارد الفرعية يعمل بشكل طبيعي؛ الصفحة المُبرمَجة لا تُطبِّق هذه القيود.
- سلبية: نُزيل ترويسات أمان وضعها الموقع المستهدف عن قصد. إن كان الموقع يستخدم عزل المشترك في المصدر لحماية بيانات حساسة من هجمات Spectre، فإن شطب هذه الترويسات يُعيد الكشف عن تلك المخاطرة.
الخيار ب: الحفاظ على COEP وCOOP.
- إيجابية: القصد الأمني للموقع المستهدف يُكرَّم.
- سلبية: أي مورد فرعي لا يضبط
CORP: cross-originصراحةً سيفشل في التحميل، محطِّماً معظم تطبيقات الويب المعقدة.
الاستراتيجية الحالية لـ ProxyOrb هي الخيار أ: تشطب البوابة Cross-Origin-Embedder-Policy وCross-Origin-Opener-Policy من الاستجابات. هذا يُعظِّم توافق المواقع. المفاضلة الأمنية مُتَّخَذة بوعي: مستخدمو خادم البروكسي يقبلون بأنهم يُشغِّلون المحتوى في بيئة مغايرة لسياق نشره المقصود.
كل آلية أمان جديدة في المتصفح تتبع نمطاً: تُطلَق كاختيار طوعي (بإمكان المواقع إرسال الترويسة إن أرادت الحماية)، ثم تُصبح تدريجياً افتراضية لواجهات API جديدة، وأخيراً يُدرَس إلزامها. سار COEP على هذا الدرب: اختياري في Chrome 83، مطلوب لـSharedArrayBuffer في Chrome 91. المواقع التي تُضمِّن محتوى طرف ثالث دون تنسيق وجدت محتواها مكسوراً. خوادم البروكسي تُضاعف هذه المشكلة لأنها بطبيعتها تتوسط في محتوى الطرف الثالث.
مجتمع أمان المتصفحات يُدرك هذه المشكلة. اقتراح Document-Isolation-Policy الناشئ يهدف إلى فصل عزل العملية عن متطلبات عزل المشترك في المصدر، مما قد يُتيح الحصول على تخفيفات Spectre دون اشتراط موافقة جميع الموارد الفرعية. حين يُطرَح، قد يتحسن توافق البروكسي مع ترويسات العزل.
6. Service Worker بوصفه طبقة الثقة من جانب المتصفح
Service Worker ليس مجرد تحسين للأداء — بل هو ضرورة معمارية لنموذج أمان ProxyOrb. إليك السبب.
نطاق التسجيل مرتبط بالمصدر
يُسجَّل Service Worker بـscope دائماً ضمن مصدر الصفحة المُسجِّلة. حين يُسجِّل ProxyOrb Service Worker الخاص به، يكون النطاق https://proxyorb.com/، مما يعني اعتراض كل طلب جلب من أي صفحة تحت ذلك المصدر.
هذا هو السبب الجوهري لنجاح إعادة الكتابة إلى المصدر نفسه: بمجرد أن يتحكم SW في عميل، فإن كل طلب شبكة من ذلك العميل — بصرف النظر عن أي URL يحاول JavaScript في الصفحة جلبه — يمر عبر Service Worker أولاً.
خط أنابيب الاعتراض
حين يعترض Service Worker طلباً، يمر عبر عدة مراحل قرار:
إعادة توجيه الترويسات بشفافية
تحدٍّ خفي: المتصفح يمنع JavaScript من تعيين بعض ترويسات الطلب "المحظورة" (Host وOrigin وReferer إلخ) عبر Fetch API. يتجاوز Service Worker ذلك بترميز الترويسات المحظورة في ترويسة مرور مخصصة واحدة؛ تفكّ البوابة ترميزها وتُطبِّقها قبل إعادة التوجيه إلى الخادم المستهدف:
التداعيات الأمنية لـ SW بوصفه وسيطاً موثوقاً
من منظور أمان الويب، يحتل Service Worker موقعاً متميزاً: بإمكانه فحص أي طلب صادر من أي صفحة في نطاقه وتعديله وتزويره. لاستخدام البروكسي المشروع، هذه هي النقطة الكاملة. لخادم بروكسي خبيث، سيكون هذا سطح هجوم بالغ القوة.
لهذا السبب تعدّ موثوقية سكريبت Service Worker نفسه أمراً بالغ الأهمية. يخدم ProxyOrb سكريبت المعترض من مصدره الخاص عبر HTTPS مع ضوابط تخزين مؤقت صارمة. لو استطاع مهاجم حقن Service Worker معدَّل، لتمكّن من اعتراض كل حركة مرور المستخدمين المتأثرين — ليس حركة البروكسي فحسب، بل أي طلب من صفحات تحت ذلك المصدر.
7. iframes: مشكلة frame-ancestors
تُمثِّل iframes تحدياً مختلفاً عن الموارد الفرعية العادية لأنها تنطوي على سياق تصفح متداخل له تصفحه الخاص، وحدوده الخاصة لـ SOP، ومجموعة قيود التضمين الخاصة به.
X-Frame-Options وframe-ancestors
آليتان تمنعان الصفحات من التضمين في iframes:
القديم: X-Frame-Options: DENY أو X-Frame-Options: SAMEORIGIN
الحديث: Content-Security-Policy: frame-ancestors 'none' أو frame-ancestors 'self'
حين تُبرمِج البوابة صفحة مستهدفة ترسل أياً من هذه الترويسات، لا يمكن تضمين الصفحة في iframe تحت مصدر البروكسي. بما أن X-Frame-Options: SAMEORIGIN يُشير إلى المصدر المستهدف (example.com)، والبروكسي يخدم الصفحة من proxyorb.com، يفشل فحص المصدر الذاتي في المتصفح.
يجب على البروكسي شطب هذه الترويسات من الاستجابات المُبرمَجة واستبدال سياسة CSP بنسخة متساهلة:
اعتراض iframes وحقن السكريبتات
تُعرِض iframes المُضمَّنة مشكلة ثانية: محتواها يُحمَّل من البروكسي، لكن سياق تصفح iframe لا يحمل تلقائياً Service Worker أو المعترض على الخيط الرئيسي نشطاً. إذا أنشأت الصفحة المُبرمَجة <iframe src="https://widget.example.com/...">, يجب إعادة كتابة URL الـiframe إلى صيغة البروكسي، وحقن سكريبتات معترض البروكسي في مستند الـiframe.
يعمل معترض iframe على مستويين:
المستوى الأول — تصحيح النموذج الأولي (Prototype) (يلتقط إنشاء iframe البرمجي):
المستوى الثاني — احتياطي MutationObserver (يلتقط iframes المُدرَجة في DOM):
مشكلة سمة sandbox
تُقيِّد سمة HTML sandbox ما يمكن لـiframe فعله: تتحكم sandbox="allow-scripts allow-same-origin" في تنفيذ السكريبت وإرسال النماذج والوصول بين المصادر وغيرها. لعمل حقن البروكسي، يحتاج iframe إلى تشغيل السكريبتات والوصول إلى سياق البروكسي الأب.
رمز allow-same-origin دقيق بشكل خاص: حين يُجمَع مع allow-scripts، يُبطِل عزل المصدر للـsandbox — يعمل iframe بمصدر الصفحة المُضمِّنة. حين يكون غائباً، يحصل iframe على مصدر غامض فريد، مما سيُعطِّل حقن سكريبت البروكسي كلياً.
نهج ProxyOrb الحالي لسمات sandbox هو إزالة سمة sandbox كلياً قبل حقن سكريبت البروكسي:
هذه مفاضلة أمنية جوهرية: الـsandboxing وُضِع عمداً من الموقع الأصلي لتقييد قدرات المحتوى المُضمَّن. إزالته توسِّع ما يمكن لذلك المحتوى فعله. هذا نوع من القرارات التي لا يراها المستخدمون النهائيون لكنها تؤثر تأثيراً ملموساً على الوضعية الأمنية لجلسة البروكسي.
8. التداعيات الأمنية على مشغّلي البروكسي
مشهد سطح الهجوم
حين يتصفح المستخدمون عبر ProxyOrb، تتدفق عدة فئات من البيانات الحساسة عبر مصدر البروكسي:
ملفات تعريف الارتباط للجلسة (Session Cookies): بما أن جميع المواقع المستهدفة تُبرمَج عبر proxyorb.com، تُخزَّن ملفات تعريف الارتباط تحت ذلك المصدر. جلسات المستخدم المُوثَّقة مع بنكه وبريده الإلكتروني وشبكاته الاجتماعية — جميعها ملفات تعريف ارتباط تحت نطاق واحد. إعداد credentials: 'include' في Service Worker يعني أن هذه الملفات تصحب كل طلب مُبرمَج.
ترويسات Referer: تكشف ترويسة Referer المُرسَلة إلى الخوادم الأصلية عن الصفحة التي كان المستخدم يعرضها. يشطب البروكسي بعناية نطاقه الخاص من قيم referer قبل إعادة التوجيه إلى الخادم المستهدف. إذا صدر طلب من https://proxyorb.com/some/path?__pot=...، تُعاد صياغة ترويسة Referer الصادرة كـURL المستهدف الأصلي (https://example.com/some/path) — لا يُسرَّب نطاق البروكسي إلى الخوادم الأصلية.
سياق تنفيذ JavaScript: كل ملف JavaScript يُخدَم عبر البروكسي يُعدَّل (تُعاد كتابة URLs فيه) ويُنفَّذ في مصدر البروكسي. سكريبت خبيث من evil.example.com مُبرمَج عبر ProxyOrb يعمل في مصدر proxyorb.com ويتمتع بوصول كامل إلى التخزين المحلي وملفات تعريف الارتباط وIndexedDB لذلك المصدر — الذي يتضمن بيانات من كل موقع مستهدف آخر وصل إليه المستخدم عبر البروكسي.
نموذج التهديد للبروكسي الخبيث
للأغراض التعليمية، من المفيد التصريح بما قد يفعله بروكسي خبيث مما يتجنبه ProxyOrb عمداً:
-
اختراق بيانات الاعتماد: يمكن لبروكسي خبيث تسجيل كل جسم طلب (يحمل كلمات المرور وبيانات النماذج) عند مروره عبر البوابة.
-
اختطاف الجلسة: نظراً لتخزين ملفات تعريف ارتباط جميع المواقع المستهدفة تحت نطاق البروكسي، يمكن لمشغّل بروكسي خبيث الوصول إلى تلك الملفات من جانب الخادم عبر البوابة.
-
حقن المحتوى: البروكسي يُعدِّل محتوى الصفحة بالضرورة (لحقن Service Worker وإعادة كتابة URLs). يمكن لبروكسي خبيث حقن JavaScript تعسفي — مسجِّلات لوحة مفاتيح، تعدين عملات مشفرة، سكريبتات احتيال إعلانية — بشكل مخفي عن المستخدم.
-
تجريد SSL: لو خفّض البروكسي اتصالات HTTPS إلى HTTP في الرابط البوابة-المستخدم، تكون حركة المرور كلها نصاً صريحاً.
يعمل ProxyOrb عبر HTTPS من طرف إلى طرف ولا يُسجِّل أجسام الطلبات. مشغّل أي خادم بروكسي ويب يمتلك هذه القدرات، وهذا هو سبب كون اختيار مشغّل بروكسي موثوق بنفس أهمية اختيار مزوّد VPN موثوق.
المحتوى المختلط (Mixed Content)
تُطبِّق المتصفحات الحديثة حجب المحتوى المختلط: لا يمكن لصفحة HTTPS تحميل موارد فرعية HTTP. يتعامل ProxyOrb مع هذا بإلزام HTTPS على جميع الاتصالات الصادرة من البوابة، حتى حين يستخدم URL المستهدف HTTP. يتضمن تجاوز CSP upgrade-insecure-requests لإرشاد المتصفح إلى ترقية أي URLs موارد فرعية HTTP إلى HTTPS قبل التحميل.
هذا مرغوب عموماً، لكنه قد يُعطِّل مواقع تخدم مواردها عمداً عبر HTTP (شبكات CDN قديمة، موارد localhost، إلخ).
9. سباق التسلح المستمر: خلاصة
حين بدأنا في بناء ProxyOrb، كانت تحديات التوافق الرئيسية CORS وX-Frame-Options. منذ ذلك الحين، أصدر Chromium CORB وCORP وCOEP وCOOP، ويطوِّر Document-Isolation-Policy. اتجاه السير واضح: تزداد المتصفحات عدوانيةً في تطبيق حدود المصادر المختلفة، وكل آلية جديدة تستدعي تكيُّف البنية التحتية للبروكسي.
التحدي الأبرز القادم على الأرجح هو النشر الكامل لـCOEP عبر تطبيقات الويب الكبرى. المواقع التي تستخدم SharedArrayBuffer للأداء (محررو الفيديو، بيئات التطوير المتكاملة، أدوات التعاون) تضبط COEP: require-corp بصورة متزايدة. بينما يشطب ProxyOrb هذه الترويسة للحفاظ على التوافق، يجد المستخدمون الذين يحتاجون الميزات عالية الأداء التي يُتيحها COEP أنها تتدهور في سياق البروكسي.
للباحثين الأمنيين، تكشف معمارية البروكسي عن شيء مهم: سياسة نفس المصدر ليست جداراً نارياً. إنها نموذج ثقة مبني على بنية URL. تستثمر خوادم البروكسي حقيقة أن SOP لا تُفرِّق جوهرياً بين "هذان المصدران من المصدر ذاته مشروعاً" و"هذان المصدران مُعادَة كتابة URLs الخاصة بهما ليبدوا من المصدر ذاته". يمكن النظر إلى الحزمة الأمنية الكاملة فوق SOP — CORS وCORB وCORP وCOEP وCOOP — باعتبارها محاولة لإضافة دفاعات أكثر متانة من هوية المصدر القائمة على URL.
فهم هذا أمر جوهري لكل من يُراجِع خدمات البروكسي، أو يصمِّم سياسات أمان المتصفحات، أو يُقيِّم الوضعية الأمنية الفعلية للتطبيقات التي قد يصل إليها المستخدمون عبر بروكسيات.
الأسئلة الشائعة
هل يتجاوز خادم البروكسي سياسة نفس المصدر؟
ليس بالضبط. يعمل خادم البروكسي عبر إعادة كتابة URL: يُحوِّل جميع URLs المصادر المختلفة إلى URLs المصدر ذاته، مما يجعل قيود SOP المتعلقة بالمصادر المختلفة غير ذات صلة بدلاً من تجاوزها. من منظور المتصفح، يبدو كل المحتوى وكأنه قادم من مصدر البروكسي الخاص، فلا تُتخطَّى أي حدود من مصادر مختلفة. هذا مختلف معمارياً عن التجاوز — لا تزال SOP تُطبِّق قواعدها؛ البروكسي يُهيِّئ المحتوى فحسب بحيث لا تُستثار تلك القواعد قط.
كيف يؤثر CORS على خوادم البروكسي للويب؟
يؤثر CORS على خوادم البروكسي على مستويين. أولاً، يجب على البروكسي اعتراض طلبات OPTIONS المبدئية والاستجابة بترويسات CORS متساهلة، إذ إن استجابة الطلب المبدئي للخادم المستهدف الفعلي (المُشيرة إلى مصدر الهدف) لن تُرضي فحص CORS للمتصفح لمصدر البروكسي. ثانياً، يجب على البروكسي شطب ترويسات CORS من استجابات الخادم المستهدف واستبدالها بترويسات تُشير إلى مصدر البروكسي. إعداد Access-Control-Allow-Credentials: true مقروناً بـcredentials: 'include' في Service Worker يعني أن جميع ملفات تعريف ارتباط مصدر البروكسي تصحب كل طلب مُبرمَج.
ما هو CORB وكيف يؤثر على خدمات البروكسي؟
حجب القراءة من المصادر المختلفة (CORB) دفاع في Chromium يمنع بعض الاستجابات الحساسة من المصادر المختلفة (HTML وJSON وXML) من الدخول إلى عملية العرض حين تُحمَّل كموارد فرعية من مصادر مختلفة. بالنسبة لخوادم البروكسي المُهيَّأة بشكل صحيح، لا يُستثار CORB عموماً لأن إعادة كتابة URL تجعل جميع الطلبات من المصدر ذاته. غير أن CORB قد يُسبِّب مشكلات خلال الفترة السابقة لتسجيل Service Worker الكامل، حين قد تنجو بعض الطلبات من إعادة الكتابة وتُرسَل كطلبات من مصادر مختلفة حقيقية. أُطلِق CORB كتخفيف لـSpectre وهو مُعرَّف في مواصفة WHATWG Fetch.
هل يمكن لخوادم البروكسي الوصول إلى ملفات تعريف ارتباط HTTP-only؟
لا. ملفات تعريف الارتباط HttpOnly تُضبَط من الخادم المستهدف ولا يمكن لـJavaScript قراءتها — بما فيه JavaScript الذي يعمل في Service Worker. غير أن البوابة تستقبل هذه الملفات حين تُعيد توجيه الطلبات نيابةً عن المستخدم، إذ يُرسِلها المتصفح في ترويسات الطلب. علامة HttpOnly تمنع سرقة JavaScript من جانب العميل، لكنها لا تمنع خادم البروكسي ذاته من رؤية قيم ملفات تعريف الارتباط أثناء العبور. هذا مماثل لكيفية حماية HttpOnly من XSS لكن ليس من الاعتراض من جانب الخادم.
هل استخدام خادم البروكسي آمن من منظور أمان المتصفح؟
يعتمد على نموذج التهديد. من منظور المتصفح، كل المحتوى المُخدَّم عبر خادم بروكسي ويب يعمل في مصدر البروكسي، مما يعني أن ثغرة في JavaScript أحد المواقع المُبرمَجة قد تصل إلى بيانات من جلسة موقع مُبرمَج آخر (إذ يتشاركان نفس مستودع ملفات تعريف الارتباط والتخزين التابع للمصدر). مشغّل البروكسي أيضاً طرف موثوق يملك الوصول إلى كل حركة المرور أثناء العبور. للوصول إلى محتوى غير حساس في بيئات مقيَّدة، المخاطرة مقبولة عادةً. لجلسات مُوثَّقة مع خدمات حساسة (مصرفية، صحية، حكومية)، يجب على المستخدمين أن يدركوا أن مشغّل البروكسي يمتلك القدرة التقنية على مراقبة تلك الحركة، وأن يستخدموا فقط خدمات بروكسي ذات سياسات عدم تسجيل قابلة للتدقيق وممارسات أمنية تشغيلية قوية.
تعكس هذه المقالة معمارية ProxyOrb كما كانت في مطلع 2026. آليات أمان المتصفحات تتطور بسرعة؛ يُنصح القراء بمراجعة معيار WHATWG Fetch ومواصفة سياسة أمان المحتوى W3C ووثائق تصميم أمان Chromium للحصول على أحدث المعلومات.
