با HTTPS و امنیت انتقال شدید HTTP، واسطه‌های مخرب را سردرگم کنید

با توجه به حجم داده‌های شخصی که در اینترنت ردوبدل می‌شود، رمزگذاری چیزی نیست که بتوانیم یا باید به‌راحتی از آن چشم‌پوشی کنیم. مرورگرهای مدرن چندین سازوکار ارائه می‌دهند که می‌توانید از آن‌ها برای اطمینان از امنیت داده‌های کاربران درحین انتقال استفاده کنید: کوکی‌های امن و امنیت انتقال سخت‌گیرانه دو مورد از مهم‌ترین آن‌ها هستند. این گواهی‌ها به شما امکان می‌دهند به‌طور یکپارچه از کاربران خود محافظت کنید، اتصال آن‌ها را به HTTPS ارتقا دهید، و تضمین کنید که داده‌های کاربر هرگز به‌صورت واضح ارسال نمی‌شود.

چرا باید به این موضوع اهمیت دهید؟ این را درنظر بگیرید:

ارائه صفحه وب ازطریق اتصال HTTP رمزگذاری‌نشده کم‌وبیش مانند این است که پاکت‌نامه‌ای باز را به اولین فردی که در خیابان می‌بینید و به‌نظر می‌رسد در مسیر اداره پست حرکت می‌کند بدهید. اگر خوش‌شانس باشید، ممکن است خودش آن را تا مقصد ببرد، یا آن را به نفر بعدی که می‌بیند و در مسیر درست حرکت می‌کند بدهد. آن شخص هم ممکن است همین کار را بکند و این روند ادامه پیدا کند.

اکثر غریبه‌ها در این زنجیره فی‌البداهه قابل‌اعتماد هستند و هرگز به نامه باز شما نگاه نمی‌کنند یا آن را تغییر نمی‌دهند. اما هرچه نامه بیشتر دست‌به‌دست شود، تعداد افرادی که به نامه ارسالی شما دسترسی کامل دارند بیشتر می‌شود. درنهایت، احتمالاً گیرنده موردنظر نامه‌تان چیزی در ایمیل دریافت خواهد کرد، اما اینکه آیا آن چیز همان چیزی است که در ابتدا تحویل داده‌اید، سؤالی بی‌پاسخ است. شاید باید آن پاکت را مهروموم می‌کردی…

واسطه‌ها

خوب یا بد، بخش‌های عظیمی از اینترنت به قابل‌اعتماد بودن غریبه‌ها متکی است. سرورها مستقیماً به یکدیگر متصل نیستند، اما درخواست‌ها و پاسخ‌ها را از مسیریابی به مسیریاب دیگر در یک بازی تلفنی عظیم منتقل می‌کنند.

می‌توانید این جهش‌ها را در عمل با traceroute ببینید. مسیر رایانه من به HTML5Rocks چیزی شبیه این است:

$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
 1  router1-lon.linode.com (212.111.33.229)  0.453 ms
 2  212.111.33.233 (212.111.33.233)  1.067 ms
 3  217.20.44.194 (217.20.44.194)  0.704 ms
 4  google1.lonap.net (193.203.5.136)  0.804 ms
 5  209.85.255.76 (209.85.255.76)  0.925 ms
 6  209.85.253.94 (209.85.253.94)  1.226 ms
 7  209.85.240.28 (209.85.240.28)  48.714 ms
 8  216.239.47.12 (216.239.47.12)  22.575 ms
 9  209.85.241.193 (209.85.241.193)  36.033 ms
10  72.14.233.180 (72.14.233.180)  43.222 ms
11  72.14.233.170 (72.14.233.170)  43.242 ms
12  *
13  lb-in-f102.1e100.net (173.194.71.102)  44.523 ms

۱۳ پرش واقعاً بد نیست. اما اگر درخواست‌ها را ازطریق HTTP ارسال کنم، هرکدام از آن رهیاب‌های واسطه به درخواست‌های من و پاسخ‌های سرور دسترسی کامل دارند. همه داده‌ها به‌صورت متن ساده رمزگذاری‌نشده منتقل می‌شوند، و هرکدام از این واسطه‌ها می‌توانند به‌عنوان مردی در میانه عمل کنند، داده‌های من را بخوانند، یا حتی آن را درحین انتقال دستکاری کنند.

بدتر اینکه این نوع رهگیری تقریباً غیرقابل‌شناسایی است. پاسخ HTTP که به‌طور مخرب اصلاح شده است دقیقاً شبیه پاسخ معتبر است، زیرا هیچ سازوکاری وجود ندارد که به شما امکان دهد مطمئن شوید داده‌های دریافتی _دقیقاً_ همان داده‌های ارسال‌شده است. اگر کسی تصمیم بگیرد اینترنت من را برای خنده زیرورو کند، کم‌وبیش بدشانسی آورده‌ام.

آیا این خط امن است؟

تغییر از HTTP متن ساده به اتصال امن HTTPS بهترین دفاع شما دربرابر واسطه‌ها است. اتصال‌های HTTPS کل کانال را به‌صورت سرتاسر پیش‌از ارسال هرگونه داده رمزگذاری می‌کنند، که باعث می‌شود خواندن یا تغییر داده‌ها درحین انتقال برای دستگاه‌های بین شما و مقصدتان غیرممکن شود.

Omnibox در Chrome جزئیات زیادی درباره وضعیت اتصال ارائه می‌دهد.
نوار نشانی Chrome جزئیات زیادی درباره وضعیت اتصال ارائه می‌دهد.

امنیت ارائه‌شده توسط HTTPS ریشه در مفهوم کلیدهای رمزنگاری عمومی و خصوصی دارد. بحث عمیق درباره جزئیات (خوشبختانه) بسیار فراتر از محدوده این مقاله است، اما فرض اصلی نسبتاً ساده است: داده‌های رمزگذاری‌شده با یک کلید عمومی معین فقط با کلید خصوصی مربوطه قابل رمزگشایی هستند. وقتی مرورگری دست‌دهی HTTPS را برای ایجاد کانال امن آغاز می‌کند، سرور گواهینامه‌ای ارائه می‌دهد که همه اطلاعات لازم را برای درستی‌سنجی هویت سرور دراختیار مرورگر قرار می‌دهد تا مرورگر بررسی کند که سرور کلید خصوصی مناسب را دراختیار دارد یا نه. از آن نقطه به بعد، همه ارتباطات به‌گونه‌ای رمزگذاری می‌شود که ثابت می‌کند درخواست‌ها به سرور اصالت‌سنجی‌شده ارسال شده‌اند و پاسخ‌ها از آن دریافت شده‌اند.

بنابراین، HTTPS به شما اطمینان می‌دهد که با سروری که فکر می‌کنید درحال صحبت هستید و هیچ‌کس دیگری به مکالمه شما گوش نمی‌دهد یا اطلاعات را در مسیر تغییر نمی‌دهد. این نوع رمزگذاری پیش‌نیاز مطلق برای امنیت در وب است؛ اگر برنامه‌تان درحال‌حاضر ازطریق HTTPS ارائه نمی‌شود، دربرابر حمله آسیب‌پذیر است. اصلاح کنید. Ars Technica راهنمای عالی برای دریافت و نصب گواهی (به‌صورت رایگان) دارد که توصیه می‌کنم برای جزئیات فنی به آن نگاهی بیندازید. پیکربندی از ارائه‌دهنده‌ای به ارائه‌دهنده دیگر و از سروری به سرور دیگر متفاوت است، اما فرایند درخواست گواهی در همه‌جا یکسان است.

پیش‌فرضاً امن

وقتی گواهینامه را درخواست و نصب کردید، مطمئن شوید که کاربرانتان از تلاش‌های شما بهره‌مند می‌شوند: کاربران موجودتان را به‌طور شفاف ازطریق جادوی تغییر مسیر HTTP به اتصال‌های HTTPS منتقل کنید و مطمئن شوید که کوکی‌ها فقط ازطریق اتصال‌های امن ارائه می‌شوند.

لطفاً از این طرف

وقتی کاربری از http://example.com/ بازدید می‌کند، با ارسال پاسخ 301 Moved Permanently با سرصفحه Location مناسب، او را به https://example.com/ هدایت کنید:

$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/

می‌توانید این نوع تغییر مسیر را به‌راحتی در سرورهایی مانند Apache یا Nginx راه‌اندازی کنید. برای مثال، پیکربندی Nginx که از http://example.com/ به https://example.com/ هدایت می‌کند به این شکل است:

server {
    listen [YOUR IP ADDRESS HERE]:80;
    server_name example.com www.example.com;
    location "/" {
        rewrite ^(.*) https://www.example.com$1 permanent;
    }
}

کوکی‌ها به ما این امکان را می‌دهند که تجربه‌های ورود به سیستم یکپارچه‌ای را ازطریق پروتکل HTTP بدون حالت به کاربران ارائه دهیم. داده‌های ذخیره‌شده در کوکی‌ها، ازجمله اطلاعات حساس مانند شناسه‌های جلسه، همراه با هر درخواست ارسال می‌شود و به سرور اجازه می‌دهد تشخیص دهد درحال‌حاضر به کدام کاربر پاسخ می‌دهد. وقتی مطمئن شدیم که کاربران ازطریق HTTPS به سایت ما دسترسی پیدا می‌کنند، باید مطمئن شویم که داده‌های حساس ذخیره‌شده در کوکی‌ها فقط ازطریق اتصال امن منتقل می‌شوند و هرگز به‌صورت واضح ارسال نمی‌شوند.

تنظیم کوکی معمولاً شامل سرایند HTTP است که چیزی شبیه به این است:

set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT

می‌توانید به مرورگر دستور دهید که استفاده از کوکی را به جلسه‌های امن محدود کند. برای این کار، یک کلیدواژه را به آن اضافه کنید:

Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure

کوکی‌های تنظیم‌شده با کلیدواژه secure هرگز ازطریق HTTP ارسال نخواهند شد.

بستن پنجره باز

هدایت شفاف به HTTPS به این معنی است که بیشتر اوقاتی که کاربران در سایت شما هستند، از اتصال امن استفاده می‌کنند. بااین‌حال، فرصت کوچکی برای حمله باقی می‌گذارد: اتصال HTTP اولیه کاملاً باز است و دربرابر حملات SSL stripping و حملات مرتبط آسیب‌پذیر است. با توجه به اینکه مرد میانی دسترسی کامل به درخواست HTTP اولیه دارد، می‌تواند به‌عنوان پروکسی بین شما و سرور عمل کند و شما را بدون توجه به اهداف سرور در اتصال HTTP ناامن نگه دارد.

می‌توانید با درخواست از مرورگر برای اجرای HTTP Strict Transport Security (HSTS)، خطر این نوع حمله را کاهش دهید. ارسال سرایند HTTP Strict-Transport-Security به مرورگر دستور می‌دهد که تغییر مسیر HTTP به HTTPS را در سمت کارخواه انجام دهد، بدون اینکه هرگز شبکه را لمس کند (این امر همچنین برای عملکرد عالی است؛ بهترین درخواست درخواستی است که مجبور به انجام آن نیستید):

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

مرورگرهایی که از این سرصفحه پشتیبانی می‌کنند (درحال‌حاضر Firefox،‏ Chrome، و Opera: caniuse جزئیات را دارد) یادداشت می‌کنند که این سایت خاص درخواست دسترسی فقط HTTPS کرده است، یعنی صرف‌نظر از اینکه کاربر چگونه به سایت می‌آید، ازطریق HTTPS بازدید خواهد کرد. حتی اگر http://example.com/ را در مرورگر تایپ کند، بدون اینکه اتصال HTTP برقرار شود، به HTTPS هدایت می‌شود. بهتر از آن، اگر مرورگر گواهینامه نامعتبری را شناسایی کند (که احتمالاً سعی دارد هویت سرور شما را جعل کند)، به کاربران اجازه داده نمی‌شود ازطریق HTTP ادامه دهند؛ یا همه یا هیچ، که عالی است.

مرورگر وضعیت HSTS سرور را پس‌از max-age ثانیه منقضی می‌کند (حدود یک ماه در این مثال)؛ این مقدار را به‌اندازه کافی بالا تنظیم کنید.

همچنین می‌توانید با افزودن دستورالعمل includeSubDomains به سرصفحه، مطمئن شوید که همه زیردامنه‌های مبدأ محافظت می‌شوند:

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

با اطمینان پیش بروید

‫HTTPS تنها راهی است که حتی از راه دور مطمئن شوید داده‌هایی که ارسال می‌کنید به‌طور کامل به گیرنده موردنظر می‌رسد. همین امروز باید اتصال‌های ایمن را برای سایت‌ها و برنامه‌هایتان راه‌اندازی کنید. این فرایند نسبتاً ساده است و به حفظ امنیت داده‌های مشتریانتان کمک می‌کند. وقتی کانال رمزگذاری‌شده‌ای را راه‌اندازی کردید، باید کاربران را به‌طور شفاف به این اتصال امن هدایت کنید، صرف‌نظر از اینکه چگونه به سایت شما می‌آیند، با ارسال پاسخ 301 HTTP. سپس مطمئن شوید که همه اطلاعات حساس جلسه کاربران شما فقط از آن اتصال امن استفاده می‌کند. برای این کار، هنگام تنظیم کوکی‌ها، کلیدواژه امن را اضافه کنید. پس‌از انجام همه این کارها، مطمئن شوید که کاربران شما هرگز به‌طور تصادفی از اتوبوس پیاده نمی‌شوند: با اطمینان از اینکه مرورگر آن‌ها با ارسال سرصفحه Strict-Transport-Security کار درست را انجام می‌دهد، از آن‌ها محافظت کنید.

راه‌اندازی HTTPS کار سختی نیست و مزایای زیادی برای سایت شما و کاربران آن دارد. ارزش تلاش کردن را دارد.

منابع

  • StartSSL گواهی‌های رایگان تأییدشده دامنه ارائه می‌دهد. هیچ‌چیز بهتر از رایگان نیست. البته ارتقا به سطوح بالاتر درستی‌سنجی هم امکان‌پذیر است و هم قیمت مناسبی دارد.
  • آزمایش سرور SSL: پس‌از راه‌اندازی HTTPS برای سرورهایتان، با اجرای آن ازطریق آزمایش سرور SSL Labs، درستی آن را تأیید کنید. گزارش مفصل و خوبی دریافت خواهید کرد که نشان می‌دهد آیا واقعاً راه‌اندازی و اجرا شده‌اید یا نه.
  • مقاله اخیر Ars Technica با عنوان «ایمن‌سازی سرور وب با SSL/TLS» ارزش خواندن دارد تا جزئیات بیشتری درباره اصول اولیه راه‌اندازی سرور به‌دست آورید.
  • مشخصات HTTP Strict Transport Security (RFC6797) ارزش مرور کردن را دارد تا همه اطلاعات فنی درباره سرایند Strict-Transport-Security را که احتمالاً می‌خواهید به‌دست آورید.
  • وقتی واقعاً بدانید چه کاری انجام می‌دهید، یک اقدام بعدی ممکن این است که تبلیغ کنید سایت شما فقط باید ازطریق مجموعه خاصی از گواهی‌ها قابل‌دسترسی باشد. در IETF کارهایی درحال انجام است که به شما امکان می‌دهد دقیقاً همین کار را ازطریق سرصفحه Public-Key-Pins انجام دهید؛ هنوز در مراحل اولیه است، اما جالب است و ارزش دنبال کردن دارد.