برمجةمن أرشيف انفورماتيك

برتوكول الـ HSTS وتطبيقه مع الـ ASP.NET MVC

الـ 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 كتالي:

قمت بإستخدام الـ Action Delegate حتى تكون الطريقة لتفعيل البرتكول شبيه بالموجودة في الـ ASP.NET Core فقط لا غير، وبإمكانك إستخدام المعاملات بدلا من الـ Action Delegate إذا أردت)

والنتيجة ستكون في المتصفح كالتالي:

لقد ذكرت في أنواع المعاملات الخاصة ببرتكول الـ HSTS ان النوع الثالث preload بأنه غير رسمي من الـ MDN، وهذا المعامل هو من قبل Google وهي أتاحت منصة لتسجيل الـ Domain الخاص في هذه المنصة، وستقوم جميع المتصفحات بإستخدم جميع التطبيقات التي تم تسجيلها في هذه المنصة وستوقم بعمل Check للتأكد من عمل تحويل للـ Request الأول أنه تم عن طريق HTTPS بإمكانك الدخول من هذا الرابط https://hstspreload.org/ ومعرفة الكثير عن الـ preload

تحياتي - محمد