مقدمه‌ای برای امنیت وب

گردآوری و تالیف : عرفان کاکایی
تاریخ انتشار : 12 شهریور 1397
دسته بندی ها : آموزشی

دلایل زیادی برای یادگیری امنیت وب وجود دارند:

  • شما یک کاربر باشید که نگران پخش شدن داده‌های شخصی خود هستید.
  • شما یک توسعه دهنده وب باشید که می‌خواهید برنامه خود را امن کنید.
  • شما یک توسعه دهنده وب، در میان یک مصاحبه باشید.
  • و...

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

دو مفهوم هسته‌ای امنیت

هیچ کس ۱۰۰ درصد امن نیست

هیچی چیزی به نام «کاملا امن و حفاظت شده علیه هک شدن» وجود ندارد و هر کسی که این را به شما بگوید، اشتباه کرده است.

یه لایه امنیت کافی نیست

نمی‌توانید بگویید که یک CSP را پیاده‌سازی کرده‌اید و حال دیگر امن هستید. به نظر علتی که بسیاری از برنامه‌نویسان این فکر را در سر دارند، این است که مقداری زیادی کد به صورت صفر و یک یا true و false نوشته‌اند. امنیت به همین سادگی نیست!

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

به اشتراک گذاری منبع میان ریشه‌ای (CORS = Cross-Origin Resource Sharing)

آیا تا به حال چنین خطایی دریافت کرده‌اید؟

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

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

هدف CORS امنیت شماست، نه صدمه زدن به شما!

در جهت توضیح نحوه کار CORS، بیایید اول درباره کوکی‌ها صحبت کنیم؛ به خصوص کوکی‌های احراز هویت. کوکی‌های احراز هویت برای این استفاده می‌شوند که به یک سرور بگوییم شما وارد شده‌اید. این کوکی‌ها، به طور خودکار به همراه هر درخواستی که به سرور ارسال می‌کنید، ارسال می‌شوند.

فرض کنید که در فیس‌بوک وارد شده‌اید، و آن‌ها از کوکی‌های احراز هویت استفاده می‌کنند. شما بر روی یک لینک که برای شما آمده است کلیک می‌کنید، که شما را به یک وبسایت مخرب انتقال می‌دهد. اسکریپتی داخل آن وبسایت مخرب، یک درخواست سمت کاربر به facebook.com ارسال می‌کند که کوکی احراز هویت شما را برای شما می‌فرستد.

در یک دنیای بدون CORS، یک گروه، می‌توانستند بدون این که شما بفهمید، تغییری به حساب کاربری شما اعمال کنند. در ابتدا آن‌ها لینک مورد نظر را بر روی timeline شما پست می‌کنند، تمام دوستان شما بر روی آن کلیک می‌کنند، سپس آن‌ها لینک مربوطه را بر روی timeline تمام دوستان شما نیز ارسال می‌کنند و به همین صورت این چرخه را ادامه می‌دهند و تمام کاربران فیس‌بوک را فتح می‌کنند، و در نهایت تمام دنیا توسط این وبسایت مخرب بلعیده می‌شود.

گرچه در دنیایی که CORS در آن وجود دارد، فیس‌بوک فقط درخواست‌هایی با منشا facebook.com را می‌پذیرد تا بتوانند داده‌های موجود بر روی سرور را ویرایش کنند. به عبارتی، آن‌ها به اشتراک گذاری منابع میان ریشه‌‌ای را محدود می‌کنند. حال ممکن است بپرسید:

«آیا آن وبسایت مخرب می‌تواند header منشا موجود بر روی درخواست خود را تغییر دهند، تا به گونه‌ای باشد که انگار از facebook.com می‌آید؟»

می‌توانند شانس خود را امتحان کنند، اما مرورگر آن را نادیده گرفته، و از منشا اصلی استفاده خواهد کرد. حال ممکن است بپرسید:

«اگر آن وبسایت درخواست خود را از سمت سرور ارسال کرد چه؟»

در این مورد، آن‌ها می‌توانند از CORS رد شوند، اما نمی‌توانند کوکی احراز هویت شما را به همراه آن درخواست ارسال کنند،‌ پس در نتیجه شکست می‌خورند. اسکریپت مربوطه باید در سمت کاربر اجرا شود تا به کوکی‌های سمت کاربر شما دسترسی داشته باشد.

سیاست امنیت محتویات (CSP = Content Security Policy)

برای درک CSP، در ابتدا باید درباره یکی از رایج‌ترین ضعف‌های موجود بر روی وب صحبت کنیم: XSS یا اسکریپت‌نویسی میان وب‌سایتی.

XSS به مواقعی می‌گویند که یک شخص مخرب یک JavaScript را به کد سمت کاربر شما تزریق می‌کند. شاید فکر کنید:

«آن‌ها چه کاری می‌خواهند انجام دهند؟ یک رنگ را از قرمز به آبی تغییر دهند؟»

بیایید فرض کنیم که یک نفر با موفقیت JavaScript را به کد سمت کاربر وبسایتی که مشاهده می‌کنید تزریق کرده است.

آن‌ها چه کار مخربی می‌توانند انجام دهند؟

  • می‌توانند یک درخواست HTTP ارسال کنند و وانمود کنند که شما هستند.
  • آن‌ها می‌توانند یک تگ anchor اضافه کنند که شما را به یک وبسایت می‌فرستد، که دقیقا به مانند آن وبسایتی که شما در حال بررسی هستید می‌باشد.
  • آن‌ها می‌توانند یک تگ script به همراه JavaScript خطی (inline) اضافه کنند.
  • آن‌ها می‌توانند یک تگ script اضافه کنند که یک فایل JavaScript کنترل از راه دور را از جایی دیگر دریافت می‌کند.
  • می‌توانند یک iframe اضافه کنند که تمام صفحه را پوشش می‌دهد و به مانند بخشی از وبسایت به نظر می‌رسد، که از شما درخواست می‌کند رمز عبور خود را وارد کنید.

امکانات موجود، بی نهایت هستند.

CSP تلاش می‌کند تا با محدود کردن این موارد، از این اتفاق جلوگیری کند:

  • چیزی که می‌تواند در یک iframe باز شود.
  • Stylesheetهایی که می‌توانند بارگذاری شوند.
  • جایی که درخواست‌ها می‌توانند ارسال شوند.
  • و...

پس CSP چگونه کار می‌کند؟

وقتی که بر روی یک لینک کلیک می‌کنید یا URL یک وبسایت را در آدرس بار مرورگر خود می‌نویسید، مرورگر شما یک درخواست GET را ارسال می‌کند. در نهایت این درخواست راه خود را به سرور پیدا می‌کند که مقداری HTML و برخی headerهای HTML را در پاسخ دریافت می‌کند. اگر درباره headerهایی که دریافت می‌کنید کنجکاو هستید، تب Network را در کنسول خود باز کرده، و چند وبسایت را مرور کنید.

شاید یک header ببینید که چنین ظاهری دارد:

content-security-policy: default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;

این محتویات سیاست امنیت facebook.com است. بیایید آن را مجددا قالب‌بندی کرده، و خوانایی آن را ساده‌تر کنیم:

content-security-policy:

default-src * data: blob:;

script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';

style-src data: blob: 'unsafe-inline' *;

connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;

حال بیایید این دستور العمل را بشکنیم.

  • default-src تمام دستور العمل‌های CSP دیگر که به صراحت لیست نشده‌اند را محدود می‌کند.
  • script-src اسکریپت‌هایی که می‌توانند بارگذاری شوند را محدود می‌کند.
  • style-src استایل‌شیت‌هایی که می‌توانند بارگذاری شوند را محدود می‌کند.
  • connect-src یو‌آر‌اِل‌هایی که می‌توانند با استفاده از رابط‌های اسکریپت مانند fetch، XHR، ajax و... بارگذاری شوند را محدود می‌کند.

دقت کنید که دستور العمل‌های CSP بیشتری از این موارد وجود دارد. مرورگر، header مربوط به CSP را می‌خواند و آن دستور العمل‌ها را به هر چیزی داخل فایل HTML که دریافت شده است اعمال می‌کند. اگر دستور العمل‌ها به درستی تنظیم شده باشند، فقط چیزی را که لازم است را رد می‌کنند.

اگر هیچ headerای برای CSP وجود نداشته باشد، همه چیز رد می‌شود و چیزی محدود نمی‌شود.

امن شدن توسط HTTPS یا HTTP

مطمئنا درباره HTTPS شنیده‌اید. شاید شنیده باشید که برخی مردم می‌گویند:

«اگر فقط در حال بازی کردن بر روی یک وبسایت هستم، چرا باید نگران HTTPS باشم؟»

یا شاید در سمت دیگر شنیده باشید:

«واقعا دیوانه هستید اگر وبسایت شما HTTPS نداشته باشد. الان در سال 2018 هستیم! به حرف دیگران اعتماد نکنید.»

شاید شنیده باشید که حال اگر وبسایت شما HTTPS نباشد، کروم آن را غیر امن در نظر می‌گیرد.

به صورت هسته‌ای، مسئله کاملا ساده است. HTTPS رمزنگاری شده است، اما HTTP اینگونه نیست.

پس اگر داده‌های حساسی ارسال و دریافت نمی‌کنید، این مسئله چه اهمیتی دارد؟

برای یک مخفف دیگر آماده شوید: MITM یا Man in the Middle. (شخص در میان) اگر از یک وای‌فای عمومی در یک کافی‌شاپ استفاده می‌کنید، عمل کردن به عنوان router شما بسیار ساده است، و تمام درخواست‌ها و پاسخ‌ها از طریق آن رد و بدل می‌شوند. اگر داده‌های شما رمزنگاری نشوند، آن‌ها می‌توانند هر کاری که می‌خواهند با آن انجام دهند. مثلا می‌توانند HTML، CSS یا JavaScript موجود را قبل از این که به مرورگر شما برسد، ویرایش کنند.

پس چگونه است که کامپیوتر و سرور من نحوه رمزنگاری / رمزگشایی را می‌دانند، اما این MITM نمی‌داند؟

SSL یا Secure Sockets Layer، (لایه سوکت‌های امن) یا اخیرا TLS یا Transport Later Security (امنیت لایه جابه‌جایی) در اینجا به میان می‌آیند. TLS در سال 1999 جای SSL را زمینه فناوری رمزنگاری استفاده شده در HTTPS گرفت. نحوه کار دقیق TLS، خارج از محدوده این مقاله است.

امنیت جابه‌جایی سخت‌گیرانه HTTP (HSTS = HTTP Strict-Transport-Security)

این مورد بسیار ساده است. بیایید header فیس‌بوک را به عنوان مثال در نظر بگیریم:

strict-transport-security: max-age=15552000; preload
  • max-age مشخص می‌کند که یک مرورگر دقیقا برای چه مدت باید به یاد داشته باشد که با استفاده از HTTPS به یک وبسایت دسترسی داشته باشد.
  • preload برای هدف ما مهم نیست. این یک سرویس میزبانی شده توسط گوگل است، نه بخشی از مشخصات HSTS.

این header فقط وقتی اعمال می‌شود که شما با استفاده از HTTPS به یک وبسایت دسترسی داشته باشید. اگر از طریق HTTP به یک وبسایت دسترسی داشته باشید، این header نادیده گرفته می‌شود. علت آن ساده است: HTTP ناامن است و نمی‌توان به آن اطمینان کرد.

کلام آخر

بدون توجه به این که در کجای راه توسعه وب هستید، امنیت وب یک مسئله مهم است. هر چه بیشتر خود را در معرض آن قرار دهید، بعدا هم راحت‌تر خواهید بود. امنیت مسئله‌ای است که باید برای همه مهم باشد.

منبع

مقالات پیشنهادی

7 راه مرسوم برای به خطر انداختن وبسایت

بلند شدن از خواب و ناپدید شدن وبسایت‌تان به نظر کمی زشت می‌آید، حتی فکر کردن در رابطه با آن جالب نیست. بلند شدن از خواب و دیدن اینکه اطلاعات کاربران و...

مقدمه‌ای بر وب انیمیشن‌ها

در این مقاله مقدماتی در رابطه با وب انیمیشن‌ها، ما قصد داریم چندین ویژگی پایه‌ای CSS را مانند pseudo-classها، transitionها و transformationها را به شم...

بهترین شیوه‌ها برای طراحی بخش جستجوی وبسایت

جستجو، می‌تواند ابزار قدرتمندی برای ارتقای تجربه کاربری باشد؛ و وقتی که از این روش‌ها پیروی کنید، می‌تواند حتی قوی‌تر هم باشد.

۸ راه برای طراحی سریع‌تر وبسایت در فوتوشاپ

به عنوان یک طراح می گویم که مرتب ماندن در کار واقعا سخت است. نه تنها به صورت همزمان باید بین چند پروژه مختلف بالانس کاری را رعایت کنید بلکه باید به رو...