الـ HSTS او ما يعرف بالـ HTTP Strict-Transport Security هو بروتكول يختص بتنبيه المتصفحات Browsers بإستخدام بروتكول الـ HTTPS وهو مثل الحلقة ما بين تطبيق الذي يعمل على الويب وما بين المتصفح.
الـ Header Type لهذا البرتكول ( HSTS ) هو Response وسوف نرى ذلك في المثال القادم. لكن دعنا نشرح بإستفاضة كيفية عمل البرتكول.
نظرة سريعة على برتوكول الـ HTTP
لكي نفهم البرتكول HSTS لابد لنا ان نضع برتكول الـ HTTP في سياقه اولا، وهو برتكول الإنترنت، بعبارة بسيطة هو المسؤول عن ربط تطبيقات الإنترنت بمزودات الخدمة ( Servers ) فمثلا عندما تقول بكتابة http://foo.com ففعليا هنا انت تستخدم الـ HTTP فهنا انت تقوم بطلب الصفحة وارسال هذا الطلب لمزود الخدمة وهو يقوم بالرد عليك بتنفيذ هذا الطلب. الشكل التالي يبين كيفية عمل هذا البرتكول:
مشكلة الـ HTTP
في مجال الحماية دائما ما يتم اختراق التطبيقات التي تعتمد على برتكول الـ HTTP ففعليا عندما تقوم بتعبئة حقول ببعض البيانات؛ تكون هذه الحقول مرئية بالنسبة لمخترقي التطبيقات فلا يتم تشفير البيانات التي قمت بملئها في تلك الحقول (الشكل التالي يوضح ذلك على سبيل المثال فقط)
بإمكانك قراء المقالة مقدمة عن بروتوكول ال HTTP للمزيد حول بروتوكول HTTP
حل مشكلة تشفير البيانات من خلال الـ HTTPS
ولحل مشكلة عدم تشفير تلك البيانات ظهر برتكول الـ HTTPS ومن مهام هذا البرتكول تشتفيرالبيانات إضافة لعمله من خلال Certificate فتكون هنالك موثوقية أكثر ما بين المتصفح والتطبيق ومزود الخدمة.
طلب البيانات الأولى من خلال الـ HTTP
عندما تقوم بكتابة أي رابط ويب على المتصفح في الغالب دائما ما يتم هذا الطلب من خلال الـ HTTP حتى وإن كنت تستخدم الـ HTTPS ( هذا في حالة قام المستخدم بكتابة HTTP://domain.com بدلا من HTTPS://Domain.com) فبعد أن تتم عملية الطلب الأول لمزود الخدمة ( Server ) يقوم مزود الخدمة بعمل إعادة توجيه لبرتكول الـ HTTPS هنا فعليا المستخدم معرض لخطر الطلب الأول والذي تم بدون تشفير للبيانات.
حل مشكلة الطلب الأول من خلال برتوكول الـ HSTS
حسنا لقد تدرجت في الشرح وأعتقد الآن انك فهمت الفرق بين الـ HTTP/HTTPS والآن لقد وصلنا للبرتكون محل هذه المقالة وهو برتكول الـ HSTS وبدون أي شرح إضافي، أعتقد تقنيا لقد فهمت المهمة الأساسية لهذا البرتكول وهي فرض اول طلب Initial Request للعمل على برتكول الـ HTTPSوتشفير البيانات.
بحسب الـ MDN لهذا البرتكول ثلاثة معاملات ( توجيهات – Directive ) وإحدى هؤلاءِ الثلاثة لا يُعتبر رسمي من قِبل الـ MDN
- Max-age وهي المدة التي سيقوم المتصفح بالإلتزام بها وعمل Redirect لأي طلب لا يستخدم الـ HTTPS وهي تلقائيا 30 يوم ومن الأفضل جعلها سنة او سنتان
- IncludeSubDomains وعو عبارة عن معامل من النوع Boolean ففي حال كان True فإنه يقوم بتطبيق الـ HSTS على الـ SubDomain المتفرعة من الـ Domain الرئيسي
- Preload وهو معامل غير رسمي وسوف أستعرض وظيفته في نهاية المقالة.
ويكون بهذا الشكل:
Strict-Transport-Security: max-age=<expire-time> Strict-Transport-Security: max-age=<expire-time>; includeSubDomains Strict-Transport-Security: max-age=<expire-time>; preload
والـ Header Type يكون عبارة عن Response كما ذكرت في بداية المقالة.
المثال العملى
سأقوم بعرض عمل البرتكول HSTS من خلال الـ ASP.NET Core والـ ASP.NET MVC 5
في الـ ASP.NET Core يمكنك تطبيق هذا البرتكول من خلال ملف الـ Startup.cs من من خلال تسجيله في الـ ConfigureService method ومن خلال تطبيقه على الـ pipeline من خلال الـ Configure method
وكما مبين في الصورة التالية:
في حالة الـ ASP.NET MVC 5 لا توجد أي Extension جاهزة للعمل عليها لكن سأقوم بعمل Implementation بصورة Custom لـ Filter ويتم تطبيقها على مستوى المشروع بصورة كاملة مهمتها العمل ببرتكول الـ HSTS
بعد أن تقوم بإنشاء المشروع، قم بعمل فئة ( class ) بإسم HSTSMetaData وستكون كالتالي:
public class HSTSHeaderMetaData
{
public TimeSpan? MaxAge { get; set; }
public bool IncludeSubDomains { get; set; } = true;
public bool Preload { get; set; }
}
بعدها قم بإنشاء Attribute بإسم HSTSAttribute وستكون كالتالي:
public class HSTSAttribute : RequireHttpsAttribute
{
HSTSHeaderMetaData data = new HSTSHeaderMetaData();
public HSTSAttribute(Action<HSTSHeaderMetaData> action) : base()
{
action(data);
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsSecureConnection)
{
StringBuilder sb = new StringBuilder($"max-age={data.MaxAge}");
if (data.IncludeSubDomains)
{
sb.Append("; includeSubDomains");
}
if (data.Preload)
{
sb.Append("; preload");
}
filterContext.HttpContext.Response.Headers.Add(
"Strict-Transport-Secutiry", sb.ToString());
}
else
{
HandleNonHttpsRequest(filterContext);
}
}
}
هذه الفئة ترث من RequireHttpsAttribute وتقوم بعمل override للأسلوب ( Method ) OnAuthorization
وقمت بالوراثة من هذه الفئة حتى استطيع ان أتاكد بأن العمل يتم أولا على برتكول الـ HTTPS
filterContext.HttpContext.Request.IsSecureConnection
فإن كان كذلك سأقوم بعمل إدراج للـ HSTS protocol للـ Header + Response بإضافة الـ Strict-Transport-Security
في الـ Constructor الخاص بالفئة قمت بإستخدام الـ Action Delegate من النوع HSTSMetaData هي الفئة التي أنشأناها أولا، وذلك حتى يتسنى لي العمل من خلال الـ Lambda Expression داخل الفئة الـ FilterConfig.cs كتالي:
والنتيجة ستكون في المتصفح كالتالي:
لقد ذكرت في أنواع المعاملات الخاصة ببرتكول الـ HSTS ان النوع الثالث preload بأنه غير رسمي من الـ MDN، وهذا المعامل هو من قبل Google وهي أتاحت منصة لتسجيل الـ Domain الخاص في هذه المنصة، وستقوم جميع المتصفحات بإستخدم جميع التطبيقات التي تم تسجيلها في هذه المنصة وستوقم بعمل Check للتأكد من عمل تحويل للـ Request الأول أنه تم عن طريق HTTPS بإمكانك الدخول من هذا الرابط https://hstspreload.org/ ومعرفة الكثير عن الـ preload
تحياتي – محمد