چک لیست ارتقاء به HTTPS مخصوص یک برنامه‌ی ASP.NET MVC 5x
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: چهار دقیقه

پس از فعالسازی HTTPS بر روی سایت خود، در جهت بهبود امنیت برنامه‌های ASP.NET MVC 5.x، می‌توان درخواست کوکی‌های صرفا ارسال شده‌ی از طریق اتصال‌های HTTPS، اجبار به استفاده‌ی از آدرس‌های HTTPS و هدایت خودکار به آدرس‌های HTTPS را نیز فعالسازی کرد.


کوکی‌هایی که باید HTTPS only شوند

کوکی‌های پیش‌فرض برنامه‌های ASP.NET به صورت HTTP Only به سمت کلاینت ارسال می‌شوند. این کوکی‌ها توسط اسکریپت‌ها قابل خوانده شدن نیستند و به همین جهت یکی از راه‌های مقاومت بیشتر در برابر حملات XSS به شمار می‌روند. پس از ارتقاء به HTTPS، این کوکی‌ها را هم می‌توان HTTPs Only کرد تا فقط به کلاینت‌هایی که از طریق آدرس HTTPS سایت به آن وارد شده‌اند، ارائه شود:
1) کوکی آنتی‌فورجری توکن
 AntiForgeryConfig.RequireSsl = true;
محل تنظیم در متد Application_Start
2) کوکی‌های حالت Forms Authentication
<configuration>
  <system.web>
    <authentication mode="Forms">
      <forms requireSSL="true" cookieless="UseCookies"/>
    </authentication>
  </system.web>
</configuration>

3) تمام httpCookies
<configuration>
  <system.web>
    <httpCookies httpOnlyCookies="true" requireSSL="true" />
  </system.web>
</configuration>

4) کوکی‌های Role manager
<configuration>
  <system.web>
    <roleManager cookieRequireSSL="true" />
  </system.web>
</configuration>
محل تنظیم این سه مورد در فایل web.config است.

5) کوکی‌های OWIN Authentication و ASP.NET Identity 2.x
var options = new CookieAuthenticationOptions()
{
    CookieHttpOnly = true,
    CookieSecure = CookieSecureOption.Always,
    ExpireTimeSpan = TimeSpan.FromMinutes(10)
};


فعالسازی اجبار به استفاده‌ی از HTTPS

با استفاده از فیلتر RequireHttps، دسترسی به تمام اکشن متدهای برنامه تنها به صورت HTTPS میسر خواهد شد:
 filters.Add(new RequireHttpsAttribute(permanent: true));
محل تنظیم در متد RegisterGlobalFilters فایل Global.asax.cs، و یا در کلاس FilterConfig به صورت زیر:
using System.Web.Mvc;
namespace MyWebsite
{
    internal static class FilterConfig
    {
        internal static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new RequireHttpsAttribute(permanent: true));
        }
    }
}
پارامتر permanent آن در چند به روز رسانی آخر MVC 5 به آن اضافه شده‌است (از نگارش 5.2.4 به بعد) و مخصوص موتورهای جستجو است؛ در جهت تصحیح خودکار آدرس‌های قدیمی سایت به آدرس‌های جدید.

همچنین در متد Application_BeginRequest نیز می‌توان بررسی کرد که آیا درخواست ارسالی یک درخواست HTTPS است یا خیر؟ اگر خیر، می‌توان کاربر را به صورت خودکار به نگارش HTTPS آن هدایت دائم کرد:
        protected void Application_BeginRequest(Object sender, EventArgs e)
        {
            if (!HttpContext.Current.Request.IsSecureConnection)
            {
                var builder = new UriBuilder
                {
                    Scheme = "https",
                    Host = Request.Url.Host,
                    // use the RawUrl since it works with URL Rewriting
                    Path = Request.RawUrl
                };
                Response.Status = "301 Moved Permanently";
                Response.AddHeader("Location", builder.ToString());
            }
        }
جهت محکم کاری این قسمت می‌توان دو تنظیم تکمیلی ذیل را نیز به فایل web.config اضافه کرد:
فعالسازی HSTS جهت اطلاع به مرورگر که این سایت تنها از طریق HTTPS قابل دسترسی است و تمام درخواست‌های HTTP را به صورت خودکار از طریق HTTPS انجام بده:
<httpProtocol>
      <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=16070400; includeSubDomains" />
و همچنین اگر ماژول URL Rewite بر روی سرور نصب است، کار هدایت خودکار به آدرس‌های HTTPS را نیز می‌توان توسط آن مدیریت کرد:
<rewrite>
    <rules>        
        <rule name="Redirect to HTTPS" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="off" ignoreCase="true" />
            <add input="{HTTP_HOST}" negate="true" pattern="localhost" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
        </rule>


اصلاح تمام آدرس‌های مطلقی که توسط برنامه تولید می‌شوند

اگر در برنامه‌ی خود از Url.Action برای تولید آدرس‌ها استفاده می‌کنید، با ذکر پارامتر protocol آن، آدرس تولیدی آن بجای یک مسیر نسبی، یک مسیر مطلق خواهد بود. اگر پیشتر این پروتکل را به صورت دستی به http تنظیم کرده‌اید، روش صحیح آن به صورت زیر است که با آدرس جدید HTTPS سایت هم سازگار است:
 var fullBaseUrl = Url.Action(result: MVC.Home.Index(), protocol: this.Request.Url.Scheme);


اصلاح تمام آدرس‌هایی که پیشتر توسط برنامه تولید شده‌اند

یک نمونه آن در مطلب «به روز رسانی تمام فیلدهای رشته‌ای تمام جداول بانک اطلاعاتی توسط Entity framework 6.x» بحث شده‌است.


اصلاح فایل robots.txt و درج آدرس HTTPS جدید

اگر در فایل robots.txt سایت، آدرس مطلق Sitemap را به صورت HTTP درج کرده بودید، آن‌را به HTTPS تغییر دهید:
User-agent: *
Sitemap: https://www.dntips.ir/Sitemap
  • #
    ‫۶ سال و ۴ ماه قبل، دوشنبه ۳۱ اردیبهشت ۱۳۹۷، ساعت ۱۳:۲۶
    یک نکته‌ی تکمیلی
    Google web master tools تغییر آدرس به HTTPS را به صورت خودکار لحاظ نمی‌کند و باید آدرس HTTPS به صورت مجزایی در آن ثبت شود. همچنین پس از این ثبت، sitemap را هم باید مجددا در آن ثبت کنید.
    البته Google analytics نیازی به اینکار ندارد و بر اساس domain کار می‌کند. 
  • #
    ‫۶ سال و ۴ ماه قبل، دوشنبه ۳۱ اردیبهشت ۱۳۹۷، ساعت ۱۷:۰۲
    روشی برای بهبود رتبه‌ی سرور در سایت ssllabs
    سایت ssllabs سرور شما را جهت یافتن مشکلات SSL اسکن می‌کند. تعداد زیادی از الگوریتم‌های رمزنگاری مرتبط با SSL تا به امروز منسوخ شده‌اند و باید از سیستم حذف شوند. برای بالابردن رتبه‌ی سرور در این حالت، اسکریپت پاورشل Setup your IIS for SSL Perfect Forward Secrecy and TLS را بر روی سرور اجرا کرده و سپس یکبار کل سرور را ری‌استارت کنید.
  • #
    ‫۶ سال و ۳ ماه قبل، جمعه ۴ خرداد ۱۳۹۷، ساعت ۲۰:۱۷
    سلام
    سایت فعلی با آدرس https://www.dntips.ir خطا دارد
    (منظور بدون www)
    • #
      ‫۶ سال و ۳ ماه قبل، شنبه ۵ خرداد ۱۳۹۷، ساعت ۰۲:۰۲
      بله. wildcard certificates در اواخر سال 2018 ارائه خواهد شد که با IIS 7.5 هم کار می‌کند. البته امکان دریافت چندین نوع مجوز به ازای زیر دامنه‌های مختلف یک سایت هم هست، اما استفاده‌ی از آن‌ها نیاز به ویژگی مخصوص «Server Name Indication» موجود در IIS سرور 2012 به بعد را دارد که فعلا در دسترس نیست (امکان داشتن بیش از یک مجوز و استفاده‌ی از آن‌ها به ازای تنها یک IP).
      - البته این مشکل با مجوزهای SAN برطرف شد. توضیحات بیشتر
  • #
    ‫۶ سال و ۳ ماه قبل، یکشنبه ۶ خرداد ۱۳۹۷، ساعت ۱۴:۵۰
    روشی بهتر برای مدیریت محتوای مخلوط (لینک به HTTP و HTTPS در یک صفحه) در مرورگرهای جدید

    در مورد محتوای مخلوط و «اصلاح تمام آدرس‌هایی که پیشتر توسط برنامه تولید شده‌اند» در مطلب فوق نکته‌ای عنوان شده‌است. روش دیگر مدیریت آن که نیازی به اصلاح محتوای صفحات سایت را ندارد، استفاده از هدر امنیتی «Content-Security-Policy: upgrade-insecure-requests» است:
    <system.webServer>
        <httpProtocol>
          <customHeaders>
            <add name="Strict-Transport-Security" value="max-age=16070400; includeSubDomains" />
            <add name="Content-Security-Policy" value="upgrade-insecure-requests;" />
          </customHeaders>
    </httpProtocol>
    کار این هدر ویژه ، ارتقاء خودکار لینک‌های درج شده‌ی در صفحات به نگارش‌های HTTPS آن‌ها است. برای مثال این تصویری است که پیش از اعمال این هدر جهت درخواست آدرس gravatar یک کاربر ارسال شده‌است و اخطار محتوای مخلوط را می‌دهد:


    و این تصویری است که پس از اعمال هدر upgrade-insecure-requests قابل مشاهده‌است که دیگر اخطار محتوای مخلوط را به همراه ندارد:
     

    • #
      ‫۶ سال و ۳ ماه قبل، سه‌شنبه ۸ خرداد ۱۳۹۷، ساعت ۱۹:۱۵
      مجبور به حذف هدر «upgrade-insecure-requests» شدم؛ چون در قسمت اشتراک‌ها، تمام Redirectهای سایت را هم تبدیل به HTTPS می‌کرد (صرفنظر از اینکه آن سایت مقصد HTTPS را پشتیبانی می‌کرد یا خیر). همین مساله مرور سایت‌های HTTP را مشکل کرده بود.
      • #
        ‫۴ سال و ۷ ماه قبل، چهارشنبه ۲۳ بهمن ۱۳۹۸، ساعت ۰۲:۰۹
        یک نکته‌ی تکمیلی
        هدر upgrade-insecure-requests از Chrome 83 (June 2020) به بعد حداقل در مورد فایل‌های دریافتی از سایت‌ها به صورت خودکار اعمال می‌شود.
  • #
    ‫۵ سال و ۳ ماه قبل، یکشنبه ۲۶ خرداد ۱۳۹۸، ساعت ۰۲:۱۴
    سلام؛ من اومدم این کار‌ها رو روی برنامه انجام دادم. حالا وقتی اجرا میکنم روی لوکال خودمم میره روی  https  و عملا نمیتونم برنامه رو اجرا کنم و تست هام رو بگیرم . https://localhost 
    پیشنهاد شما برای رفع این مشکل چی هست ؟