WEB

امنیت وب چیست؟ مفاهیم پایه برای مدیران و توسعه‌دهندگان

علیرضا کیا
علیرضا کیا
کارشناس وب و موبایلبازبینی: ۲۵ مرداد ۱۴۰۵
۲۵ فروردین ۱۴۰۵ ۱۴ دقیقه مطالعه

برای اینکه بتوانید درباره‌ی امنیت سامانه‌ی خود تصمیم بگیرید — چه بودجه‌ای بگذارید، چه سؤالی از پیمانکار بپرسید، کدام یافته‌ی گزارش را جدی بگیرید — نیازی نیست پنتستر شوید. اما به یک مدل ذهنی درست از سازوکار وب نیاز دارید. امنیت وب چیزی جدا از معماری وب نیست؛ مجموعه‌ای از پیامدهای مستقیم همان معماری است. این مقاله همان مدل ذهنی را از پایه می‌سازد، بدون فرض دانش قبلی.

در یک نگاه

  • وب بر پایه‌ی HTTP کار می‌کند: پروتکلی بی‌حالت که هر درخواست را مستقل می‌بیند. تمام سازوکار «ورود کاربر» چیزی است که روی این بی‌حالتی ساخته شده.
  • HTTPS فقط مسیر انتقال را رمزنگاری می‌کند. درباره‌ی درستی کد شما هیچ چیز نمی‌گوید.
  • احراز هویت یعنی «تو کی هستی» و مجوزدهی یعنی «اجازه‌ی چه کاری داری». اکثر رخنه‌های جدی از خرابی دومی می‌آیند.
  • سیاست هم‌مبدأ بنیادی‌ترین مرز امنیتی مرورگر است؛ CORS آن را شل می‌کند، نه محکم‌تر.
  • قاعده‌ای که همه‌چیز به آن برمی‌گردد: هیچ داده‌ای که از کلاینت می‌آید قابل اعتماد نیست — نه فیلد مخفی، نه اعتبارسنجی جاوااسکریپت، نه هدر.

امنیت وب چیست؟ یک تعریف کاربردی

امنیت وب یعنی حفظ سه ویژگی برای سامانه و داده‌ی شما:

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

نکته‌ی مهم این است که هر سه‌ی این‌ها را کد و پیکربندی خود شما تأمین می‌کند، نه یک محصول جانبی. یک برنامه‌ی وب در ذات خود یک درِ باز به دنیاست: شما عمداً به میلیون‌ها کاربر ناشناس اجازه می‌دهید کد شما را اجرا کنند و به پایگاه‌داده‌ی شما کوئری بزنند — البته با محدودیت‌هایی که خودتان تعریف کرده‌اید. امنیت وب، مهندسیِ همان محدودیت‌هاست.

در ادامه، هر لایه از این معماری را می‌بینیم و در هر لایه مشخص می‌کنیم چه چیزی می‌تواند خراب شود.

HTTP: پروتکلی که هیچ‌چیز را به یاد نمی‌آورد

هر تعامل با یک سایت، یک درخواست (Request) از مرورگر و یک پاسخ (Response) از سرور است. شکل ساده‌شده‌ی یک درخواست:

GET /account/invoices HTTP/1.1
Host: example.com
Cookie: session=a1b2c3...
User-Agent: Mozilla/5.0 ...

سه بخش را ببینید: متد (اینجا GET؛ متدهای دیگر POST، PUT، DELETE)، مسیر، و هدرها. پاسخ هم یک کد وضعیت دارد (۲۰۰ موفق، ۴۰۳ ممنوع، ۵۰۰ خطای سرور) به‌همراه هدرها و بدنه.

حالا ویژگی‌ای که همه‌چیز از آن نتیجه می‌شود: HTTP بی‌حالت (stateless) است. سرور به‌طور طبیعی هیچ حافظه‌ای از درخواست قبلی ندارد. از دید HTTP، درخواست دومِ همان کاربر یک غریبه‌ی کامل است.

پس «کاربر وارد شده است» چطور کار می‌کند؟ با یک قطعه داده که مرورگر در هر درخواست دوباره ارسال می‌کند — همان که در مثال بالا در هدر Cookie دیدید. تمام امنیت نشست، از همین یک نقطه شروع می‌شود.

نکته‌ی عملی برای مدیران: هر چیزی که کاربر می‌فرستد — مسیر، پارامتر، هدر، کوکی، بدنه — کاملاً در کنترل اوست. مرورگر تنها یکی از راه‌های ساختن یک درخواست HTTP است. یک ابزار خط فرمان مثل curl یا یک پروکسی میان‌گیر می‌تواند هر درخواستی را با هر مقداری بسازد. این جمله بدیهی به‌نظر می‌رسد اما ریشه‌ی بخش بزرگی از آسیب‌پذیری‌های واقعی است.

HTTPS و TLS: چه چیزی را محافظت می‌کنند و چه چیزی را نه

HTTP به‌تنهایی متن روشن است؛ هر کسی در مسیر می‌تواند آن را بخواند و تغییر دهد. HTTPS همان HTTP است که داخل TLS پیچیده شده. TLS سه چیز می‌دهد:

  • رمزنگاری: ناظر مسیر محتوا را نمی‌بیند.
  • یکپارچگی: اگر کسی در مسیر داده را تغییر دهد، تشخیص داده می‌شود.
  • هویت سرور: گواهی، تأیید می‌کند که شما با example.com حرف می‌زنید نه با کسی که خود را جای آن زده است.

خط پایه‌ی امروزی: TLS 1.3 فعال، TLS 1.2 فقط برای سازگاری و آن هم محدود به مجموعه‌رمزهای ECDHE با AEAD، و TLS 1.0 و 1.1 کاملاً غیرفعال — این دو رسماً منسوخ شده‌اند و مذاکره‌ی آن‌ها ممنوع است. هر چیزی با نام SSL از دو دهه پیش منسوخ است؛ اصطلاح «گواهی SSL» فقط یک نام تجاری جامانده است.

باور غلط رایج

«سایت ما HTTPS دارد پس امن است.» قفل سبز مرورگر فقط می‌گوید مسیر رمزنگاری شده و هویت دامنه تأییدشده است. درباره‌ی اینکه کد شما تزریق SQL دارد یا نه، اینکه کنترل دسترسی درست است یا نه، یا اینکه پنل مدیریت با رمز admin باز می‌شود یا نه، هیچ چیز نمی‌گوید. یک سایت فیشینگ هم می‌تواند HTTPS داشته باشد. اگر با خطای گواهی روبه‌رو شده‌اید، راهنمای خطای گواهی SSL علت‌های رایج را توضیح می‌دهد.

یک تکمیل مهم: HTTPS داشتن کافی نیست، باید اجباری باشد. هدر Strict-Transport-Security (یعنی HSTS) به مرورگر می‌گوید این دامنه را همیشه با HTTPS باز کن — و همین جلوی حمله‌ی تنزل به HTTP را می‌گیرد که یکی از سناریوهای رسمی سرقت کوکی نشست است.

کوکی و نشست: کلید خانه‌ی کاربر

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

پس سه چیز اهمیت حیاتی دارد: شناسه باید غیرقابل حدس باشد، در مسیر نشت نکند، و از سمت سرور قابل ابطال باشد. صفت‌های کوکی ابزار همین کارند:

صفت کوکیکاری که می‌کندچه چیزی را جلوگیری می‌کند
Secureکوکی فقط روی HTTPS ارسال می‌شودنشت کوکی روی اتصال متن‌روشن
HttpOnlyجاوااسکریپت به کوکی دسترسی نداردسرقت نشست از طریق XSS
SameSite=Lax یا Strictمحدود کردن ارسال کوکی در درخواست‌های بین‌سایتیبخشی از CSRF — نه همه‌ی آن
پیشوند __Host-کوکی را به دقیقاً همان دامنه و مسیر ریشه مقید می‌کندتزریق کوکی از یک زیردامنه
انقضای کوتاه + ابطال سمت سرورعمر مفید کلید دزدیده‌شده را کم می‌کنداستفاده‌ی طولانی‌مدت از نشست ربوده‌شده
باور غلط رایج

«همه‌ی مرورگرها امروز به‌صورت پیش‌فرض SameSite=Lax اعمال می‌کنند، پس CSRF حل شده است.» کروم این کار را می‌کند، اما فایرفاکس نه — موزیلا این تغییر را پس از مشاهده‌ی خرابی گسترده‌ی وب کنار گذاشت و باگ مربوطه با وضعیت WONTFIX بسته شد. سافاری هم سازوکار متفاوتی دارد. نتیجه: توکن CSRF سمت سرور همچنان الزامی است، و صفت SameSite را باید صریحاً خودتان تعیین کنید نه اینکه به پیش‌فرض مرورگر کاربر تکیه کنید.

احراز هویت در برابر مجوزدهی: تفاوتی که همه‌چیز است

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

  • احراز هویت (Authentication) پاسخ به «تو کی هستی؟» است. ورود با رمز عبور، کد یک‌بارمصرف، ورود با گوگل — همه احراز هویت‌اند.
  • مجوزدهی (Authorization) پاسخ به «اجازه‌ی انجام این کار روی این داده را داری؟» است. و این پرسش باید در هر درخواست و برای هر رکورد پرسیده شود.

خطای کلاسیک این است که برنامه فقط اولی را انجام دهد: «کاربر وارد شده است، پس اجازه دارد». نتیجه‌اش این می‌شود که کاربر ثبت‌نام‌شده‌ی الف با تغییر یک شماره در آدرس، داده‌ی کاربر ب را می‌بیند. نام فنی این خانواده IDOR است و زیرمجموعه‌ی کنترل دسترسی شکسته است — که در فهرست OWASP Top 10:2025 رتبه‌ی یک را دارد و OWASP گزارش می‌کند در داده‌ی این نسخه، ۱۰۰٪ برنامه‌های آزموده‌شده نوعی نقص کنترل دسترسی داشته‌اند.

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

همین‌جا روشن می‌شود چرا هیچ اسکنر خودکاری این دسته را پیدا نمی‌کند: ابزار نمی‌داند کاربر شماره‌ی ۵ باید رکورد شماره‌ی ۷ را ببیند یا نه. این تشخیص به فهم قواعد کسب‌وکار نیاز دارد و همین است که تست نفوذ دستی را از اسکن جدا می‌کند.

سیاست هم‌مبدأ: مرز امنیتی مرورگر

مرورگر شما در همان لحظه چند سایت را باز دارد. چه چیزی مانع می‌شود که یک تب مخرب، محتوای تب بانک شما را بخواند؟ پاسخ: سیاست هم‌مبدأ (Same-Origin Policy یا SOP).

«مبدأ» ترکیب سه چیز است: پروتکل، دامنه و پورت. یعنی https://example.com و http://example.com و https://api.example.com سه مبدأ متفاوت هستند. قاعده‌ی SOP این است: جاوااسکریپتِ یک مبدأ نمی‌تواند پاسخ درخواست به مبدأ دیگر را بخواند. توجه کنید که ارسال درخواست معمولاً ممکن است؛ چیزی که ممنوع می‌شود خواندن پاسخ است. همین تفکیک ظریف، دلیل وجود CSRF است: درخواست می‌رود و اثرش را می‌گذارد، حتی اگر مهاجم پاسخ را نبیند.

گاهی لازم است این محدودیت را عمداً شل کنید — مثلاً وقتی برنامه‌ی تک‌صفحه‌ای شما روی یک دامنه است و API روی دامنه‌ی دیگر. سازوکار استاندارد این کار CORS است: سرور با هدرهایی مثل Access-Control-Allow-Origin اعلام می‌کند کدام مبدأها اجازه‌ی خواندن پاسخ را دارند.

باور غلط رایج

«CORS یک قابلیت امنیتی است که از API ما محافظت می‌کند.» دقیقاً برعکس. CORS سیاست هم‌مبدأ را شل می‌کند؛ هرگز چیزی به امنیت اضافه نمی‌کند. یک تنظیم سهل‌انگارانه‌ی CORS محافظت را برمی‌دارد. بدترین حالت رایج، سروری است که هر مبدأیی را که در درخواست بیاید بازتاب می‌دهد و در کنارش Access-Control-Allow-Credentials: true می‌فرستد — این یعنی هر سایتی می‌تواند داده‌ی احراز هویت‌شده‌ی کاربران شما را بخواند.

مرز اعتماد: هیچ‌چیزی از کلاینت قابل اعتماد نیست

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

  • مقدار فیلدهای فرم، از جمله فیلدهای hidden و disabled.
  • هر اعتبارسنجی سمت کلاینت — maxlength، الگوی regex در HTML، بررسی جاوااسکریپتی فرم.
  • هدرها، از جمله User-Agent، Referer و هدرهای سفارشی برنامه.
  • کوکی‌هایی که با HttpOnly محافظت نشده‌اند، و هر چیزی در localStorage.
  • ترتیب و توالی درخواست‌ها — مهاجم می‌تواند مرحله‌ی دو را بدون مرحله‌ی یک صدا بزند.
  • قیمت، تخفیف، شناسه‌ی کاربر و نقش، اگر در بدنه‌ی درخواست ارسال می‌شوند.

پیامد عملی این قاعده در طراحی: هر اعتبارسنجی سمت کلاینت فقط برای تجربه‌ی کاربری است و باید عیناً در سمت سرور تکرار شود. اگر منطق «مبلغ نهایی» در مرورگر محاسبه و به سرور فرستاده می‌شود، سرور باید آن را دور بیندازد و خودش محاسبه کند. اگر «نقش کاربر» در توکن یا فیلد فرم می‌آید، سرور باید نقش را از پایگاه‌داده‌ی خودش بخواند.

همین‌جا مفهوم سطح حمله (Attack Surface) معنا پیدا می‌کند: هر نقطه‌ای که داده‌ی بیرونی وارد سامانه می‌شود. فرم‌ها، پارامترهای URL، APIها، آپلود فایل، وب‌هوک‌ها، هدرها، و حتی نام فایلی که کاربر آپلود می‌کند. برای هر یک از این نقاط، این پرسش را بپرسید: «اگر این مقدار چیزی جز آنچه انتظار دارم باشد، چه می‌شود؟» — که تعریف عملی مدل‌سازی تهدید است. برای درک تفاوت باگ معمولی و آسیب‌پذیری، آسیب‌پذیری چیست را ببینید.

هدرهای امنیتی: دستورهایی که به مرورگر می‌دهید

بخشی از دفاع، در مرورگر کاربر اجرا می‌شود — به‌شرط اینکه سرور شما به مرورگر بگوید چه کار کند. این کار با هدرهای پاسخ انجام می‌شود:

هدرچه می‌کندیادداشت عملی
Strict-Transport-Securityمرورگر را مجبور می‌کند همیشه HTTPS استفاده کندبا max-age طولانی؛ پیش از فعال‌سازی مطمئن شوید همه‌ی زیردامنه‌ها HTTPS دارند
Content-Security-Policyمشخص می‌کند کدام اسکریپت‌ها اجازه‌ی اجرا دارندمؤثرترین شکلش CSP بر پایه‌ی nonce است، نه فهرست دامنه
X-Content-Type-Options: nosniffجلوی حدس زدن نوع محتوا توسط مرورگر را می‌گیردارزان و بدون عارضه؛ همیشه فعال کنید
Referrer-Policyمحدود می‌کند چه بخشی از آدرس به سایت‌های بیرونی نشت کندمانع نشت توکن یا شناسه از طریق آدرس
frame-ancestors در CSPجلوی جاسازی صفحه در iframe سایت دیگر را می‌گیردجانشین مدرن X-Frame-Options برای Clickjacking

یک هشدار مهم درباره‌ی CSP: نوشتن سیاستی که فهرستی از دامنه‌های مجاز باشد، در عمل تقریباً همیشه قابل دور زدن است. پژوهش گوگل روی سیاست‌های واقعی نشان داد ۱۴ دامنه از ۱۵ دامنه‌ی پرکاربرد در فهرست‌های مجاز، اندپوینت ناامن داشتند و اکثریت قاطع سیاست‌های بررسی‌شده قابل دور زدن بودند. شکل درست، سیاست بر پایه‌ی nonce همراه با strict-dynamic است. و مهم‌تر: CSP یک کاهنده‌ی اثر است، نه اصلاح آسیب‌پذیری. اگر XSS دارید، CSP آسیب را کم می‌کند اما باگ سر جایش است.

مدل ذهنی نهایی و قدم بعدی

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

  1. HTTP بی‌حالت است؛ نشست چیزی است که خودتان روی آن ساخته‌اید و باید از آن مثل کلید خانه محافظت کنید.
  2. HTTPS مسیر را ایمن می‌کند، برنامه را نه.
  3. احراز هویت کافی نیست؛ مجوزدهی باید در هر درخواست و برای هر رکورد بررسی شود.
  4. سیاست هم‌مبدأ مرز مرورگر است؛ CORS آن را شل می‌کند.
  5. هیچ داده‌ای از کلاینت قابل اعتماد نیست — سرور مرجع نهایی است.

با این مدل ذهنی، بقیه‌ی مباحث معنا پیدا می‌کنند. برای دیدن اینکه این مفاهیم در ده دسته‌ی رسمی ریسک چطور دسته‌بندی می‌شوند، راهنمای امنیت وب اپلیکیشن را بخوانید. اگر مالک سایت هستید و به‌دنبال کارهای عملی هستید، راهنمای امنیت سایت نقطه‌ی شروع مناسب‌تری است. و برای مرور اصطلاحات فنی، دانشنامه‌ی پی‌هانتر — از CSRF و CORS تا TLS — هر مفهوم را جداگانه توضیح می‌دهد.

اگر می‌خواهید بدانید این مفاهیم در سامانه‌ی خودتان چقدر درست پیاده شده‌اند، مشاوره‌ی اولیه نقطه‌ی شروع بدون هزینه‌ای است و می‌توانید سؤال‌های همین مقاله را مبنای گفتگو قرار دهید.

پرسش‌های متداول

امنیت وب چیست و شامل چه چیزهایی می‌شود؟

امنیت وب یعنی حفظ محرمانگی، یکپارچگی و دسترس‌پذیری برنامه‌ی وب و داده‌ی آن. در عمل شامل امن‌سازی کد برنامه، مدیریت نشست و احراز هویت، کنترل دسترسی، پیکربندی درست سرور و TLS، هدرهای امنیتی مرورگر، مدیریت وابستگی‌ها، و ثبت رخداد و پایش می‌شود.

آیا HTTPS داشتن به این معنی است که سایت من امن است؟

نه. HTTPS فقط مسیر انتقال داده را رمزنگاری می‌کند و هویت دامنه را تأیید می‌کند. اگر کد شما تزریق SQL دارد، پنل مدیریت رمز ضعیف دارد، یا کنترل دسترسی درست پیاده نشده، HTTPS هیچ کمکی نمی‌کند. سایت‌های فیشینگ هم HTTPS دارند.

تفاوت احراز هویت و مجوزدهی چیست؟

احراز هویت مشخص می‌کند کاربر کیست (ورود با رمز، کد یک‌بارمصرف). مجوزدهی مشخص می‌کند آن کاربر اجازه‌ی چه کاری روی چه داده‌ای را دارد. اکثر رخنه‌های جدی از خرابی مجوزدهی می‌آید — کاربری که درست وارد شده اما به داده‌ی دیگران دسترسی پیدا می‌کند.

سیاست هم‌مبدأ چیست و چرا مهم است؟

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

چرا می‌گویند نباید به داده‌ی سمت کلاینت اعتماد کرد؟

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

به‌عنوان مدیری که برنامه‌نویس نیست، از کجا شروع کنم؟

سه پرسش را از تیم فنی بپرسید و پاسخ مکتوب بگیرید: آیا کنترل دسترسی در سمت سرور و برای هر رکورد بررسی می‌شود؟ آیا همه‌ی پنل‌های مدیریت احراز هویت چندعاملی دارند؟ آیا فهرست کتابخانه‌های استفاده‌شده و نسخه‌هایشان را داریم و چه کسی CVEها را رصد می‌کند؟ پاسخ این سه سؤال وضعیت کلی شما را نشان می‌دهد.

علیرضا کیا
WRITTEN BY

علیرضا کیا

کارشناس وب و موبایل

متخصص تست نفوذ وب و اندروید با سابقه‌ی مدیریت تیم نفوذ در داتین. مهندسی معکوس اپ‌ها و کشف ذخیره‌سازی ناامن، تخصص اوست.

WEB

امنیت سایت: راهنمای جامع برای مدیران

ادامه مطلب ←
WEB

امنیت وب اپلیکیشن؛ راهنمای جامع بر پایه OWASP

ادامه مطلب ←
BASICS

امنیت سایبری چیست؟ و برای امنیت اطلاعات چه کنیم؟

ادامه مطلب ←