Featured image of post Cookies - SameSite Attribute

Cookies - SameSite Attribute

Cookies - SameSite Attribute

Photo by Mohammad Rahmani on Unsplash

بدءاً من الإصدار 84، عيّن Chrome خاصية SameSite لملفات تعريف الارتباط (Cookies) افتراضياً إلى Lax. قد تتأثر الخدمات التي تستخدم Third-party cookies إذا لم تقم بتعيين SameSite بشكل صحيح.

نظرة عامة

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

 

First-Party and Third-Party

بناءً على مصدر ملف تعريف الارتباط (Set-Cookie)، لكل ملف تعريف ارتباط نطاق (Domain) محدد. عند النظر إلى الرابط الحالي في متصفح المستخدم، إذا كان نطاق ملف تعريف الارتباط يطابق الرابط الحالي، فهو First-Party؛ وإلا فهو Third-Party.

Third-party

على سبيل المثال، عند تصفح الموقع a.com، يتم إرسال طلب (request) إلى third-party.com ويستقبل ملف تعريف ارتباط من third-party.com. نظراً لأن المتصفح يضمّن تلقائياً ملفات تعريف الارتباط التي لها نفس النطاق في الطلبات، فإذا تصفحت لاحقاً موقعاً آخر مثل b.com وأرسل أيضاً طلباً إلى third-party.com، فسيتلقى الخادم ملف تعريف الارتباط. بالنسبة لهذين الموقعين، يُعتبر ملف تعريف الارتباط الخاص بـ third-party.com هو Third-party.

First-party

إذا تصفحت موقعاً إلكترونياً يطابق نطاق third-party.com، فسيتم إرسال ملف تعريف الارتباط أيضاً. في هذه الحالة، يسمى ملف تعريف الارتباط هذا First-party.

 

Same-Origin and Same-Site

أشار المثال السابق إلى استخدام النطاق لتحديد نوع ملف تعريف الارتباط، ولكن الطريقة الأفضل لقول ذلك هي تحديد ما إذا كان الموقع (Site) هو نفسه. هل يتعلق هذا بـ Same-origin الذي نراه كثيراً؟

Cookies SameSite

Origin

يتكون الأصل (Origin) من المخطط (Scheme)، والمضيف (Host)، والمنفذ (Port). طريقة التحديد بسيطة للغاية: إذا كان المخطط، والمضيف، والمنفذ لرابطين متطابقين تماماً، فهما Same-origin؛ وإلا فهما Cross-origin.

Site

يتضمن تحديد Same-Site نطاقات المستوى الأعلى الفعالة (eTLDs). يتم تعريف جميع eTLDs في Public Suffix List، ويتكون الموقع (Site) من eTLD بالإضافة إلى بادئة (prefix).

على سبيل المثال: github.io موجود في Public Suffix List. إضافة بادئة (مثل a.github.io) يجعله موقعاً. لذلك، a.github.io و b.github.io هما موقعان مختلفان (Cross-site).

example.com غير موجود في Public Suffix List، ولكن .com موجود، لذا example.com هو موقع، و a.example.com و b.example.com هما الموقع نفسه (Same-site).

لاحظ أن الموقع لا يتضمن المنفذ، لذلك حتى إذا كانت المنافذ مختلفة، فلا يزال من الممكن أن يكونا Same-site.

 

Why SameSite?

جلبت الآلية التي “يحمل فيها أي طلب ملفات تعريف الارتباط الخاصة بذلك النطاق” أيضاً مشكلات أمنية وغيرها، وأهمها تزوير الطلب عبر المواقع (CSRF).

CSRF

لنفترض أن مستخدماً قام بتسجيل الدخول إلى example.com وحصل على ملف تعريف ارتباط. عندما يتصفح المستخدم موقعاً ضاراً evil.com، يمكن لـ JavaScript في ذلك الموقع إرسال طلب POST إلى example.com/pay?amount=1000. سيقوم المتصفح تلقائياً بتضمين ملف تعريف ارتباط example.com، ويدفع المستخدم 1000 دولار دون علمه. لا يمكن للخادم تحديد مصدر هذا الطلب.

القيود

لا يمكن تعيين ملفات تعريف الارتباط نفسها بحيث يتم إرسالها فقط في بيئة First-party، لذلك تحمل الطلبات ملفات تعريف الارتباط في أي بيئة. لا يمكن للخادم تحديد مصدر الطلب ويمكنه فقط الاستجابة كالمعتاد، مما يتسبب في إهدار العميل للنطاق الترددي في إرسال ملفات تعريف ارتباط غير مفيدة.

الحل

باستخدام خاصية SameSite، يمكننا تكوين شروط إرسال ملفات تعريف الارتباط بشكل فردي في بيئات مختلفة.

SameSite

تحتوي خاصية SameSite على ثلاث قيم. يمكن أن يؤدي تعيينها إلى Strict أو Lax إلى تقييد إرسال ملفات تعريف الارتباط في طلبات Same-Site فقط. إذا تُركت فارغة، فإن السلوك يعتمد على المتصفح؛ بالنسبة لـ Chrome، القيمة الافتراضية هي Lax.

Strict

يتم إرسال ملفات تعريف الارتباط فقط في بيئة First-party. ومع ذلك، هناك مشكلة: لنفترض أن المستخدم يرى رابط منشور فيسبوك على example.com (لنقل fb.com). حتى إذا قام المستخدم بتسجيل الدخول إلى fb.com وكان لديه ملف تعريف ارتباط، فإن النقر فوق الرابط لن يرسل ملف تعريف الارتباط لأن الموقعين هما Cross-site، لذلك سيرون صفحة تسجيل الدخول فقط.

لذلك، Strict مناسب للإجراءات الحساسة، مثل حذف المنشورات، وإجراء المدفوعات، وما إلى ذلك.

Lax

لمعالجة القيود الصارمة للغاية لـ Strict، يسمح Lax بإرسال ملفات تعريف الارتباط حتى في مواقف Cross-site في الحالات التالية:

  • كتابة رابط في شريط العنوان
  • النقر فوق رابط <a href="...">
  • إرسال نموذج <form method="GET">
  • العرض المسبق (Prerendering) <link rel="prerender" href="...">

تشترك هذه الحالات في نقطتين: جميعها طلبات GET وجميعها تؤدي إلى التنقل في المستوى الأعلى (Top-level Navigation). هذا يتجنب مشكلة Strict التي تتطلب تسجيل الدخول مرة أخرى في كل مرة، ويمنع أيضاً إرسال ملفات تعريف الارتباط دون علم عند تصفح مواقع ويب أخرى.

Lax + POST

ومع ذلك، لتجنب كسر بعض تدفقات تسجيل الدخول الحالية، يخفف Chrome حالياً القيود قليلاً لـ SameSite=Lax، مما يمنح المطورين مزيداً من الوقت للتكيف.

في غضون دقيقتين من تعيين ملف تعريف الارتباط، بغض النظر عن طريقة الطلب (Request Method)، طالما أنه يؤدي إلى تنقل في الصفحة ذات المستوى الأعلى، فسيتم إرسال ملف تعريف الارتباط. هذا يعني أنه إذا قام المتصفح بتغيير الصفحة، على سبيل المثال إرسال نموذج <form method="POST">.

للتفاصيل، يرجى الاطلاع على الموضوع حول Lax + POST.

None

لإرسال Third-party cookie، يجب عليك تعيين SameSite=None; Secure. نعم، من الآن فصاعداً، إذا كنت ترغب في إرسال Third-party cookie في بيئة اختبار، يرجى تحضير https://localhost.

بالإضافة إلى ذلك، يتطلب إرسال Cross-Origin Requests عبر XHR/Fetch تعيين withCredentials: true لإرسال ملف تعريف الارتباط وجعل Set-Cookie في رأس الاستجابة فعالاً. يجب أن يقوم الخادم أيضاً بتعيين Access-Control-Allow-Credentials: true في رأس الاستجابة لكي يتمكن JavaScript من الوصول إلى محتوى الاستجابة.

المتصفحات غير المدعومة

لا تدعم جميع المتصفحات قواعد SameSite الأحدث حتى الآن، لذلك يمكن إضافة بعض الحلول المؤقتة (Workarounds) على الخادم لدعم متصفحات متعددة:

تعيين كلا ملفي تعريف الارتباط

يمكن لهذه الطريقة حل المشاكل لجميع المتصفحات تقريباً، ولكن الجانب السلبي هو أنه سيكون هناك نسختان من ملف تعريف الارتباط:

Set-cookie: name=value; SameSite=None; Secure
Set-cookie: name-legacy=value; Secure

رمز الخادم:

if (req.cookies['name']) {
  // استخدم الجديد إذا كان متاحاً
  cookieVal = req.cookies['name'];
} else if (req.cookies['name-legacy']) {
  // وإلا استخدم القديم
  cookieVal = req.cookies['name-legacy'];
}

User Agent

تحديد المتصفح باستخدام User agent للطلب لتقرير محتوى Set-Cookie. تتطلب هذه الطريقة تعديل الرمز الذي يعين ملف تعريف الارتباط فقط، دون تغيير جزء التحليل (Parsing). ومع ذلك، فإن طريقة الحكم هذه تتضمن المزيد من المتغيرات وتجعل من السهل تعيين ملف تعريف الارتباط الخاطئ.

 

مراجعة

  • سيتم تعيين ملفات تعريف الارتباط التي لم يتم تعيين خاصية SameSite لها افتراضياً إلى SameSite=Lax ولا يمكن إرسالها في بيئة Cross-site.
  • لإرسال ملفات تعريف الارتباط في Cross-site، تحتاج إلى تعيين SameSite=None; Secure.
  • يمكنك استخدام SameSite sandbox لاختبار ما إذا كان متصفحك الحالي يتوافق مع أحدث قواعد SameSite.

Reference

All rights reserved,未經允許不得隨意轉載
مبني بستخدام Hugo
قالب Stack مصمم من Jimmy