الطلب الذي لا يراه إعادة التوجيه لديك أبدًا
يفعل كل موقع تقريبًا لديه شهادة الأمر نفسه: يجيب المنفذ 80 بتوجيه 301 إلى عنوان https://. وهذا صحيح، وينبغي أن تُبقيه. لكنه يحدث بعد طلب واحد فات أوانه.
حين يكتب أحدهم example.com في شريط العنوان، أو يتبع رابطًا من رسالة بريد إلكتروني قديمة، أو يفتح إشارة مرجعية من سنوات مضت، لا يملك المتصفح أي سبب لافتراض HTTPS. يفتح اتصال HTTP صريحًا ويطلب الصفحة. يجيب توجيهك — لكن السؤال أُرسل بالفعل بنص صريح، عبر أي شبكة يصادف أن يكون عليها الزائر: مقهى، مطار، فندق، بوابة أسيرة، راوتر منزلي لم يحدّثه أحد.
كل من يستطيع قراءة ذلك الطلب يستطيع أيضًا الإجابة عنه. فبدل تمرير توجيهك 301، يقدّم نسخته الخاصة من موقعك عبر HTTP، ويمرّر كل شيء بهدوء إليك عبر HTTPS خلف الكواليس. يرى الزائر صفحة تبدو صحيحة، إلا قفلًا لا يتحقق منه أحد تقريبًا، ويكتب كلمة مرور فيها. يُسمّى هذا انتزاع SSL (SSL stripping)، وهو هجوم تنزيل موجَّه بالضبط إلى الطلب الذي وُجد توجيهك أصلًا لإصلاحه.
يزيل HSTS ذلك الطلب من الوجود. فبمجرد أن يرى المتصفح الترويسة، يعيد كتابة http://example.com/... إلى https://... داخليًا، قبل أن يغادر أي شيء الجهاز. فلا يوجد طلب بنص صريح لاعتراضه، ولا تحذير شهادة يمكن للزائر أن ينقر متجاوزًا إياه.
ما الذي تقوله الترويسة
Strict-Transport-Security: max-age=31536000 هي كل الأمر عمليًا. يمكن أن تظهر فيها ثلاثة إعدادات، وتتفاوت تفاوتًا كبيرًا في مقدار ما تلزمك به.
max-age هو الوحيد المطلوب: عدد الثواني التي ينبغي للمتصفح أن يتذكّر خلالها أن هذا المضيف HTTPS فقط. 31536000 هي سنة. وتُعاد الساعة عند كل استجابة، فالموقع الذي يُزار بنشاط يبقى أمامه دائمًا سنة كاملة، بينما ينساه في النهاية موقع لا يزوره أحد.
يوسّع includeSubDomains القاعدة إلى كل اسم تحت نطاقك — www، وapi، وshop، وstaging، والاسم الذي نسيته. وهو أقوى فعليًا، لأن ملف تعريف الارتباط الموضوع على نطاق أب يمكن مهاجمته عبر أي نطاق فرعي منه. وهو أيضًا الإعداد الذي يكسر الأشياء، لأنه يطبَّق على مضيفات قد لا تتحكم بها وقد لا تملك شهادات لها.
يطلب preload إدراج نطاقك مضمَّنًا داخل المتصفحات نفسها، فيُطبَّق HTTPS فقط حتى قبل أن يزور الزائر موقعك يومًا. ويتطلب includeSubDomains وmax-age طويلًا، ومن الصعب جدًا التراجع عنه.
ثمة قاعدة واحدة تجمع الثلاثة: لا تُحتسب الترويسة إلا في استجابة HTTPS. وتتجاهلها المتصفحات عمدًا عبر HTTP الصريح، لأن احترامها هناك سيسمح لأي شخص على الشبكة بتثبيت نطاق لا يملكه.
لماذا نرسل max-age فقط
يرسل الإعداد الجاهز على cdn.com.tr max-age=31536000 وليس أكثر. وهذا افتراضي متعمَّد لا قيدًا، ويستحق أن نفهم ما كان سيلزمك به الإعدادان الآخران.
يصل includeSubDomains إلى أسماء ليست أمامك على الصفحة التي فعّلته فيها: مضيف mail. قديم على خادم عتيق، صفحة status.، أداة داخلية على نطاق فرعي أجاب بـHTTP الصريح لسنوات. فبمجرد أن يحمل المتصفح القاعدة، يصبح كل واحد منها غير قابل للوصول في ذلك المتصفح — ليس تحذيرًا، بل فشلًا صريحًا — وإزالة الترويسة لا تُصلح ذلك، لأن المتصفح دوّن القاعدة بالفعل.
يفشل preload في الاتجاه نفسه، لكن بأبطأ: فسحبه تقديمُ طلب إلى قائمة طرف ثالث، ثم انتظار إصدارات المتصفحات لتشحنه، وهو ما يُقاس بالأشهر.
يمنحك max-age لمدة سنة على المضيف الذي تخدمه فعليًا كامل الفائدة الأمنية لذلك المضيف منذ أول زيارة. أما الأعلام الأقوى فتستحق الإضافة لاحقًا، عن قصد، بمجرد أن يُجرَد كل اسم تحت نطاقك وينتقل إلى HTTPS. ابدأ من حيث تستطيع أن تكون متيقنًا، لا من حيث قد تندم.
قائمة التحقق قبل أن تفعّله
HSTS ليس خطرًا. تفعيله على موقع غير جاهز هو الخطر. اعمل على هذه القائمة أولًا.
كل صفحة تُحمَّل عبر HTTPS. ليس فقط الصفحة الرئيسية: منطقة الإدارة، وAPI، ونقاط رفع الملفات، وأهداف الـwebhook، وروابط حملات قديمة. أي شيء يعمل فقط على المنفذ 80 يتوقف عن العمل لكل من رأى الترويسة.
الشهادة صالحة وتجدّد نفسها. تحت HSTS، لم تعد الشهادة المنتهية تحذيرًا يمكن للزائر تجاوزه — بل جدارًا. تُصدَر الشهادات على cdn.com.tr وتُجدَّد تلقائيًا، وهي بالضبط الخاصية التي يفترضها HSTS متوفرة لديك.
لا محتوى مختلط. ينبغي أن تكون السكربتات وأوراق الأنماط والصور والإطارات المشار إليها بـhttp:// مُصلَحة سلفًا؛ HSTS يجعل فشلها أعلى صوتًا فحسب.
أنت تعرف ما تفعله نطاقاتك الفرعية. لا لأنك تفعّل includeSubDomains اليوم، بل لأنك سترغب في ذلك يومًا ما، والجرد هو العمل الفعلي.
يبقى توجيهك من HTTP إلى HTTPS في مكانه. يحمي HSTS المتصفحات التي رأت الترويسة؛ والتوجيه يلتقط كل من سواها. فهما ليسا بديلين أحدهما عن الآخر.
تفعيله
في اللوحة، افتح قواعد التوصيل ← إعدادات الأمان الجاهزة (Delivery rules → Security presets). حقل "إعداد الأمان" هو قائمة اختيار متعدد لإعدادات الحافة الجاهزة المطبَّقة على الحساب: اختر Hsts واحفظ. تقع الصفحة على /management/cdn/advanced-management.
الإعداد لكل حساب، فالمضيف الذي لم يجهز بعد يمكن ببساطة أن ينتظر على حساب خاص به بدل أن يعطّل الحسابات الجاهزة.
بمجرد الحفظ، تضيف الحافة الترويسة إلى استجابات HTTPS لذلك الحساب فقط — يظل طلب HTTP الصريح يحصل على توجيهك، دون ترويسة مرفقة، وهو السلوك الذي تشترطه المواصفة. لا يتغيّر شيء في أصلك: لا ترويسة تضيفها في nginx أو Apache أو إطار عملك، لأن الحافة هي حيث يُقرَّر الردّ الظاهر للزائر.
التحقق منه خلال عشر ثوانٍ
اطلب الترويسات وابحث عن السطر الواحد. نتيجتان تهمّان، والثانية هي التي يتخطاها الناس.
الترويسة مكانها استجابات HTTPS وحدها
# should print: strict-transport-security: max-age=31536000
curl -sI https://example.com/ | grep -i strict-transport
# should print nothing at all
curl -sI http://example.com/ | grep -i strict-transport
ما الذي يتذكّره المتصفح
يخبرك سطر الأوامر بما ترسله. أما المتصفح فهو حيث تؤدي الترويسة عملها فعليًا، ويستحق أن تتأكد مرة أن القاعدة وصلت.
زُر الموقع عبر HTTPS، ثم افتح تبويبًا جديدًا واكتب اسم المضيف المجرد. ينبغي أن يقفز شريط العنوان مباشرة إلى https:// — تحدث إعادة الكتابة داخل المتصفح، فلا يوجد طلب على السلك يمكن اعتراضه ولا توجيه يُتَّبع. يعرض Chrome ما خزّنه عند chrome://net-internals/#hsts، بما في ذلك تاريخ الانتهاء، وهو مفيد حين تختبر بدل أن تخمّن.
عادتان توفّران عليك الحيرة هنا. اختبر من ملف تعريف متصفح لم يزر الموقع قط حين تريد رؤية سلوك أول زيارة، وتذكّر أن المتصفح الذي تعلّم القاعدة قبل أن تغيّر أي شيء سيبقى يتصرف بموجبها — وهذا موضوع القسم التالي.
التراجع، وما لا يقدر التراجع على فعله
أزل تحديد Hsts من قائمة الاختيار المتعدد نفسها واحفظ. تتوقف الحافة عن إرسال الترويسة فورًا، ويتصرف أي متصفح لم يرها قط بشكل طبيعي منذ تلك اللحظة.
ما لا يحدث هو الجزء الذي يفاجئ الناس: تستمر المتصفحات التي سجّلت القاعدة بالفعل في فرضها حتى تنتهي مدة max-age لديها. إيقاف الإعداد الجاهز لا يصل إليها. فبمدة max-age لسنة واحدة، سيظل زائر رأى الترويسة بالأمس يفرض HTTPS لسنة كاملة بصرف النظر عمّا يقوله خادمك الآن.
توفّر المواصفة فعلًا تراجعًا تدريجيًا لتلك الحالة — فإرسال الترويسة بـmax-age=0 يخبر المتصفح بأن ينسى القاعدة في زيارته التالية عبر HTTPS. لكن هذا لا يعمل إلا ما دام الموقع لا يزال متاحًا عبر HTTPS، ويجب أن يستمر إرساله حتى تعود المتصفحات التي تهمك، فهو انسحاب مخطَّط له لا مفتاح تبديل.
ولهذا تهم قائمة التحقق أكثر من خطة التراجع. الفشل الواقعي ليس أبدًا "كان HSTS خطأ بالنسبة لنا"؛ بل "رابط واحد كان يعمل عبر HTTP فقط واكتشفنا ذلك لاحقًا". وإصلاح ذلك الرابط هو غالبًا الطريق الأسرع للعودة.
أين يقع HSTS بين حمايتك الأخرى
لا يفعل HSTS إلا شيئًا واحدًا بالضبط: يزيل الطلب بنص صريح. ويستحق التوضيح، لأن "لدينا HSTS" تُقال أحيانًا وكأن السؤال الأمني قد أُجيب عنه الآن.
إنه ليس شهادة — بل يفترض شهادة صالحة ويجعل الشهادة غير الصالحة قاتلة. وليس تشفيرًا؛ ذلك ما يفعله TLS، وHSTS يضمن فقط أن TLS هو ما يُستخدم. لا يفحص شيئًا، فلا يوقف أي حقن أو ثغرة أو حمولة خبيثة: ذلك عمل WAF. لا يعدّ شيئًا، فيبقى التخمين والكشط عمل تحديد المعدل. ولا يقول شيئًا عمّن يمكنه الوصول إليك، وهنا يأتي دور حجب البلد وASN.
ما يجعله يستحق خمس دقائق هو النسبة: ترويسة واحدة، إعداد واحد، لا صيانة مستمرة — وفئة كاملة من هجمات التنزيل تتوقف عن أن تكون ممكنة ضد زوّارك.
الأسئلة الشائعة
هل يكفي HSTS وحده؟
لا، وليس المقصود منه ذلك. يضمن HSTS أن الاتصال مشفّر؛ ولا يقول شيئًا عمّا يسافر عبره. فالطلب الحامل لحقن SQL يصل بأمان عبر HTTPS كما يصل عبر HTTP. مكانه إلى جانب شهادة صالحة، وWAF، وتحديد معدل، وقواعد وصول معقولة — لا بدلًا منها.
هل يحل HSTS محل توجيهي من HTTP إلى HTTPS؟
لا. أبقِ التوجيه. لا يُطبَّق HSTS إلا بعد أن يكون المتصفح قد رأى الترويسة مرة واحدة على الأقل عبر HTTPS، فكل زائر لأول مرة، وكل جهاز جديد، وكل زاحف، يصل عبر المنفذ 80 ويحتاج إلى التوجيه 301. يغطي كل منهما نصفًا مختلفًا من المشكلة نفسها.
هل يغطي نطاقاتي الفرعية؟
ليس مع هذا الإعداد الجاهز. فهو يرسل max-age فقط، وتنطبق القاعدة على اسم المضيف المحدد الذي قدّم الاستجابة. تغطية النطاقات الفرعية تتطلب includeSubDomains، وهو التزام أكبر بكثير: يسري في المتصفح فورًا ولا يمكن سحبه من هناك، فلا بد أن يكون كل اسم تحت نطاقك يعمل على HTTPS قبل أن تفكر فيه.
هل ينبغي أن أقدّم نطاقي إلى قائمة HSTS preload؟
فقط بعد أن يكون HTTPS في كل مكان مملًا لأشهر. يضع preload نطاقك داخل المتصفح، فيحمي حتى أول طلب على الإطلاق من الزائر — لكن الإزالة تعني تقديم طلب إلى طرف ثالث وانتظار إصدارات المتصفحات، فالخطأ يدوم طويلًا. يمنحك max-age لمدة سنة معظم الفائدة ويبقي طريق العودة مفتوحًا.
هل يحمي HSTS أول زيارة على الإطلاق لأحدهم؟
بذاته، لا — تلك هي الثغرة الوحيدة التي يتركها. أول زيارة هي ما يعلّم المتصفح القاعدة، ويحميها توجيهك وشهادة صالحة لا HSTS. وpreload هو الطريقة الوحيدة لسدّ تلك الثغرة، ولهذا توجد القائمة.
هل سيؤثر في الأداء؟
بشكل طفيف لصالحك. الترويسة بضع عشرات من البايتات، وبمجرد أن يحملها المتصفح، تُعاد كتابة كل رابط http:// إلى موقعك داخل المتصفح بدل أن يكلّف رحلة ذهاب وإياب إلى توجيهك. الزوار الذين كانوا يصلون سابقًا عبر توجيه 301 يتخطّونه تمامًا.