جستجو
برای جستجو متن مورد نظر وارد کنید و Enter بزنید برای بستن Esc بزنید.
امنیت یک وبسایت فقط به استفاده از HTTPS یا نصب افزونههای امنیتی محدود نمیشود. مرورگر نیز بخشی از امنیت سایت را از طریق Security Headers مدیریت میکند. این هدرهای HTTP به مدیران سایت و توسعهدهندگان اجازه میدهند نحوه اجرای اسکریپتها، بارگذاری منابع، استفاده از iframe، ارتباطات Cross-Origin و دسترسی به قابلیتهای مرورگر را کنترل کنند. در این آموزش، مهمترین هدرهای امنیتی HTTP، کاربرد هرکدام و روش تنظیم آنها در Apache، Nginx و وردپرس را بهصورت فنی بررسی میکنیم.
امنیت یک وبسایت فقط به استفاده از HTTPS، نصب فایروال یا انتخاب یک رمز عبور قوی محدود نمیشود. مرورگر هنگام دریافت پاسخ از سرور، مجموعهای از دستورها را نیز دریافت میکند که مشخص میکنند صفحه چگونه باید بارگذاری شود، چه منابعی اجازه اجرا دارند، آیا سایت میتواند داخل یک iframe نمایش داده شود و مرورگر چه اطلاعاتی را هنگام ارسال درخواست در اختیار سایتهای دیگر قرار دهد.
این دستورها معمولاً از طریق HTTP Response Header ارسال میشوند و بهطور کلی با عنوان Security Headers شناخته میشوند.
هدرهای امنیتی بهتنهایی یک وبسایت را امن نمیکنند، اما میتوانند سطح حمله مرورگر را کاهش دهند و لایهای مهم در معماری دفاعی وبسایت ایجاد کنند. MDN نیز CSP، HSTS، X-Content-Type-Options، X-Frame-Options، Referrer-Policy و هدرهای Cross-Origin را از مکانیزمهای مهم امنیت وب معرفی میکند.
Security Headers مجموعهای از HTTP Response Headerها هستند که سرور برای کنترل رفتار مرورگر ارسال میکند.
برای مثال، سرور میتواند در پاسخ HTTP چنین هدرهایی را ارسال کند:
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
مرورگر این اطلاعات را هنگام دریافت پاسخ پردازش میکند و بر اساس آنها محدودیتهایی را روی نحوه اجرای صفحه اعمال خواهد کرد.
یکی از مهمترین تفاوتهای Security Headers با راهکارهایی مانند WAF این است که بسیاری از این هدرها مستقیماً رفتار User Agent را کنترل میکنند. برای مثال CSP مشخص میکند مرورگر چه منابعی را برای یک صفحه مجاز به بارگذاری یا اجرا بداند.
هنگامی که کاربر آدرس یک صفحه را باز میکند، مرورگر یک HTTP Request به سرور ارسال میکند.
سرور پس از پردازش درخواست، یک HTTP Response برمیگرداند. این پاسخ معمولاً شامل بخشهایی مانند Status Code، Response Header و Body است.
یک پاسخ ساده میتواند چیزی شبیه نمونه زیر باشد:
HTTP/2 200 OK
Content-Type: text/html; charset=UTF-8
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
<!DOCTYPE html>
<html>
...
</html>
در این مثال، مرورگر قبل از پردازش محتوای HTML، هدرهای ارسالشده را دریافت میکند.
بنابراین Security Header را نباید صرفاً یک متادیتای ساده در HTML تصور کرد. این دستورها بخشی از پاسخ HTTP هستند و برخی از آنها فقط زمانی معتبر هستند که بهصورت Response Header از طریق HTTP ارسال شوند.
برای نمونه، قرار دادن X-Frame-Options داخل تگ <meta> باعث فعال شدن این مکانیزم نمیشود. MDN صراحتاً تأکید میکند که X-Frame-Options باید بهعنوان HTTP Header ارسال شود.
همه هدرهای امنیتی کاربرد یکسانی ندارند. بعضی از آنها تقریباً برای هر وبسایت عمومی مفید هستند، در حالی که برخی دیگر به معماری خاص سایت و نحوه استفاده از منابع وابستهاند.
Content-Security-Policy یکی از مهمترین مکانیزمهای امنیتی سمت مرورگر است.
CSP به وبسایت اجازه میدهد مشخص کند مرورگر چه منابعی را میتواند بارگذاری یا اجرا کند. این سیاست میتواند منابع JavaScript، CSS، تصویر، فونت، iframe و درخواستهای شبکه را کنترل کند.
کاربرد اصلی CSP کاهش ریسک حملاتی مانند Cross-Site Scripting یا XSS است. CSP همچنین میتواند برای محدود کردن embedding و ارتقای درخواستهای HTTP به HTTPS مورد استفاده قرار گیرد.
یک Policy ساده:
Content-Security-Policy: default-src 'self'
یعنی در حالت پایه، منابع فقط از Origin خود سایت مجاز هستند.
البته این Policy برای بسیاری از سایتهای واقعی کافی نیست.
فرض کنید سایت از Google Fonts، یک CDN، Google Analytics و YouTube استفاده میکند. در چنین شرایطی باید منابع موردنیاز را بهصورت دقیق در Policy تعریف کرد.
برای مثال:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.example.com;
style-src 'self' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
img-src 'self' data: https:;
connect-src 'self' https://analytics.example.com;
frame-src https://www.youtube.com;
این Policy صرفاً نمونه آموزشی است و نباید بدون بررسی منابع واقعی سایت روی یک پروژه تولیدی قرار گیرد.
default-src
منبع پیشفرض بسیاری از Directiveهای دریافت منابع را تعیین میکند.
script-src
منابع JavaScript مجاز را مشخص میکند.
style-src
منابع CSS مجاز را کنترل میکند.
img-src
منابع مجاز تصاویر را تعیین میکند.
font-src
منابع فونت را محدود میکند.
connect-src
مقاصد مجاز برای درخواستهایی مانند Fetch، XMLHttpRequest و WebSocket را کنترل میکند.
frame-src
مشخص میکند iframeهای صفحه اجازه بارگذاری محتوا از چه منابعی را دارند.
frame-ancestors
تعیین میکند چه Originهایی اجازه دارند صفحه شما را داخل iframe قرار دهند.
این Directive با frame-src تفاوت مهمی دارد. frame-src درباره iframeهایی است که صفحه شما بارگذاری میکند، در حالی که frame-ancestors مشخص میکند چه سایتی اجازه دارد صفحه شما را embed کند.
object-src
میتواند برای محدود کردن منابعی مانند <object> استفاده شود.
base-uri
استفاده از <base> را محدود میکند.
form-action
مقاصدی را که فرمهای سایت اجازه ارسال داده به آنها دارند مشخص میکند.
فعالکردن CSP در یک سایت بزرگ بدون تست میتواند باعث از کار افتادن برخی قابلیتها شود.
برای همین میتوان ابتدا Policy را در حالت گزارشدهی آزمایش کرد:
Content-Security-Policy-Report-Only:
default-src 'self';
در این حالت Policy نقضشده گزارش میشود اما مانند CSP معمولی الزاماً بارگذاری منبع را مسدود نمیکند. MDN نیز Content-Security-Policy-Report-Only را برای آزمایش Policy و مشاهده نقض قوانین بدون اعمال آنها معرفی میکند.
این روش برای سایتهای وردپرسی و پروژههایی که تعداد زیادی اسکریپت و سرویس شخص ثالث دارند اهمیت زیادی دارد.
هدر HTTP Strict Transport Security که با نام HSTS شناخته میشود، به مرورگر اعلام میکند که سایت باید از طریق HTTPS استفاده شود.
نمونه:
Strict-Transport-Security: max-age=31536000
در این مثال مرورگر سیاست را برای یک سال نگه میدارد.
نسخه گستردهتر:
Strict-Transport-Security: max-age=31536000; includeSubDomains
و در سناریوهای مناسب:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
HSTS در برابر سناریوهایی مانند SSL Stripping یا Downgrade کمک میکند. با فعال بودن HSTS، مرورگر در بازدیدهای بعدی میتواند درخواست HTTP را مستقیماً به HTTPS تبدیل کند.
اما فعالسازی includeSubDomains و مخصوصاً استفاده از preload باید با دقت انجام شود. تمام زیر دامنههایی که تحت سیاست قرار میگیرند باید واقعاً از HTTPS پشتیبانی کنند.
مستندات فعلی MDN برای HSTS همچنین مقدار حداقل یکسال max-age را در شرایط لازم برای Preload ذکر میکند.
این Header برای جلوگیری از MIME Sniffing استفاده میشود.
مقدار متداول آن:
X-Content-Type-Options: nosniff
با این تنظیم، مرورگر باید MIME Type اعلامشده در Content-Type را جدی بگیرد و در شرایط مشخص از حدسزدن نوع فایل جلوگیری کند.
برای نمونه، اگر فایل JavaScript با MIME Type نادرست ارسال شود، nosniff میتواند باعث شود مرورگر آن را بهعنوان Script معتبر پردازش نکند.
این Header ساده است و در بسیاری از پیکربندیهای امنیتی وب توصیه میشود.
X-Frame-Options مشخص میکند صفحه سایت اجازه دارد در <frame>، <iframe>، <embed> یا <object> نمایش داده شود یا خیر.
رایجترین مقدار:
X-Frame-Options: DENY
در این حالت صفحه نباید در Frame نمایش داده شود.
گزینه دیگر:
X-Frame-Options: SAMEORIGIN
که embedding را به همان Origin محدود میکند.
این Header یکی از راهکارهای قدیمی و شناختهشده برای کاهش ریسک Clickjacking است.
در پروژههای جدید، CSP و بهخصوص Directive frame-ancestors انعطاف بیشتری ارائه میکند. MDN نیز frame-ancestors را جایگزین منعطفتری برای X-Frame-Options معرفی میکند.
مرورگر هنگام انتقال کاربر از یک صفحه به صفحه دیگر ممکن است اطلاعاتی درباره صفحه قبلی را از طریق Referer ارسال کند.
Referrer-Policy میزان این اطلاعات را کنترل میکند.
یک انتخاب متداول:
Referrer-Policy: strict-origin-when-cross-origin
در این حالت، هنگام درخواستهای Same-Origin اطلاعات بیشتری حفظ میشود، اما در درخواستهای Cross-Origin معمولاً فقط Origin ارسال میشود و هنگام انتقال از HTTPS به HTTP اطلاعات Referrer ارسال نمیشود. این Policy در حال حاضر Default مرورگرها نیز محسوب میشود.
برای سایتهایی که URL آنها حاوی اطلاعات حساس است، تنظیم Referrer Policy اهمیت بیشتری پیدا میکند.
Permissions-Policy به سایت اجازه میدهد استفاده از برخی قابلیتهای مرورگر را محدود کند.
برای مثال:
Permissions-Policy: geolocation=()
با این تنظیم، استفاده از Geolocation در آن محدوده سیاستی مسدود میشود.
یا میتوان دسترسی را فقط برای Originهای مشخص مجاز کرد:
Permissions-Policy:
geolocation=(self "https://example.com")
این سیاست میتواند قابلیتهایی مانند Camera، Microphone و Geolocation را کنترل کند. ساختار آن بر اساس Directive و Allowlist تعریف میشود.
نکته مهم این است که پشتیبانی مرورگرها برای همه قابلیتهای Permissions Policy یکسان نیست و قبل از استفاده در محیط Production باید Compatibility بررسی شود.
در پروژههای مدرن، کنترل ارتباط میان Originهای مختلف اهمیت زیادی دارد.
سه Header مهم در این حوزه عبارتاند از:
Cross-Origin-Opener-Policy
Cross-Origin-Resource-Policy
Cross-Origin-Embedder-Policy
COOP میتواند ارتباط یک صفحه با browsing contextهای متعلق به Originهای دیگر را محدود کند.
نمونه:
Cross-Origin-Opener-Policy: same-origin
CORP برای کنترل درخواستها و دسترسی منابع از Originهای دیگر کاربرد دارد.
نمونه:
Cross-Origin-Resource-Policy: same-origin
COEP نحوه استفاده از منابع Cross-Origin در یک سند را محدود میکند.
این سه Header در کنار هم در برخی معماریهای امنیتی پیشرفته اهمیت پیدا میکنند. MDN هر سه را در دسته هدرهای امنیتی HTTP قرار میدهد.
خیر.
این یکی از اشتباهات رایج هنگام افزایش امنیت سایت است.
هدف امنیت، فعالکردن بیشترین تعداد Header نیست. هدف ایجاد Policy متناسب با معماری سایت است.
برای مثال اگر سایت از iframe استفاده میکند، فعالکردن:
X-Frame-Options: DENY
ممکن است یک قابلیت ضروری را از کار بیندازد.
همین مسئله درباره CSP نیز وجود دارد. Policy زیر:
script-src 'self'
ممکن است باعث مسدود شدن اسکریپتهای ضروری سرویسهای خارجی شود.
بنابراین قبل از اعمال Security Headers باید منابع، Scriptها، iframeها، CDNها، APIها و سرویسهای شخص ثالث سایت شناسایی شوند.
اگر سایت روی Apache اجرا میشود، یکی از روشهای رایج استفاده از .htaccess است.
نمونه:
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Strict-Transport-Security "max-age=31536000"
</IfModule>
دستور always اهمیت دارد زیرا باعث میشود Header در پاسخهایی که شرایط خاصی دارند نیز اعمال شود.
برای CSP نیز میتوان نمونهای مانند زیر داشت:
Header always set Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self';"
اما CSP را نباید بدون بررسی منابع سایت کپی و فعال کرد.
در Nginx میتوان از add_header استفاده کرد:
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000" always;
برای CSP:
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self';" always;
در محیط Production باید رفتار Nginx، Proxy، CDN و Origin در کنار یکدیگر بررسی شود. ممکن است Header در Origin تنظیم شده باشد اما لایه دیگری آن را حذف یا تغییر دهد.
در وردپرس چند روش وجود دارد.
روش اول، تنظیم Header در وبسرور است که معمولاً انتخاب مناسبی برای کنترل مرکزی Policy محسوب میشود.
روش دوم، استفاده از افزونههای امنیتی است.
روش سوم، اعمال Header در لایه CDN یا Reverse Proxy است.
برای یک سایت وردپرسی حرفهای، بهتر است ابتدا مشخص شود Header در کدام لایه تولید میشود. اعمال یک Header در چند لایه مختلف بدون بررسی میتواند باعث ایجاد Policyهای متناقض یا چند مقدار متفاوت شود.
سادهترین روش استفاده از ابزارهای توسعهدهنده مرورگر است.
در Chrome یا مرورگرهای مبتنی بر Chromium:
DevTools → Network → انتخاب Request → Headers → Response Headers
در این قسمت میتوان Response Headerهای واقعی ارسالشده توسط سرور را مشاهده کرد.
روش دیگر استفاده از curl است:
curl -I https://example.com
یا:
curl -sI https://example.com
خروجی چیزی شبیه این خواهد بود:
HTTP/2 200
content-type: text/html; charset=UTF-8
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
این روش برای وبمسترها و توسعهدهندگان بسیار مفید است، زیرا Header واقعی پاسخ سرور را مشاهده میکنید و به تنظیمات پنل مدیریت سایت وابسته نیستید.
یکی از خطرناکترین اشتباهات، کپی کردن یک کانفیگ آماده بدون شناخت معماری سایت است.
اشتباهات مهم شامل موارد زیر هستند:
فعالکردن CSP سختگیرانه بدون تست
ممکن است JavaScript، فونت، تصویر یا iframe موردنیاز سایت مسدود شود.
استفاده بیدلیل از Wildcard
قرار دادن * در Policyهای حساس میتواند محدودیت امنیتی موردنظر را تا حد زیادی کاهش دهد.
استفاده گسترده از unsafe-inline
این مقدار در CSP میتواند بخشی از مزیت امنیتی سیاست مربوط به Scriptهای Inline را کاهش دهد و باید با توجه به معماری برنامه استفاده شود.
فعالکردن HSTS بدون بررسی زیر دامنهها
استفاده از includeSubDomains میتواند تمام زیر دامنهها را تحت سیاست HTTPS قرار دهد.
اعتماد به نمره ابزارهای تست
یک امتیاز بالا در ابزارهای بررسی Header به معنی امن بودن کامل وبسایت نیست.
Security Headers فقط یک لایه از امنیت هستند و جایگزین Secure Coding، کنترل دسترسی، مدیریت Session، بهروزرسانی نرمافزار، WAF، مانیتورینگ و Backup نمیشوند.
برای سایتی که معماری آن بررسی شده و به این Policyها نیاز دارد، میتوان یک نقطه شروع شبیه نمونه زیر در نظر گرفت:
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self';
این نمونه کانفیگ عمومی برای کپی کردن روی هر سایتی نیست. CSP، HSTS و Frame Policy باید بر اساس ساختار واقعی پروژه بررسی شوند.
برای مثال سایتی که باید توسط سرویس دیگری داخل iframe قرار گیرد، نباید صرفاً به دلیل توصیه یک چکلیست DENY را فعال کند.
Security Headers مستقیماً جایگزین تکنیکهای سئو نیستند و نباید آنها را یک فاکتور رتبهبندی مستقل در نظر گرفت.
اهمیت آنها بیشتر از منظر امنیت و قابلیت اطمینان وبسایت است. HTTPS، جلوگیری از اجرای منابع ناخواسته، کنترل محتوای شخص ثالث و کاهش برخی حملات میتوانند به حفظ سلامت فنی سایت کمک کنند.
از طرفی یک CSP اشتباه میتواند منابع ضروری صفحه را مسدود کند و عملکرد سایت را مختل سازد. بنابراین اجرای Security Headers باید با تست واقعی سایت همراه باشد.
| Header | کاربرد اصلی | اولویت |
|---|---|---|
| Content-Security-Policy | کنترل منابع و کاهش ریسک XSS | بسیار بالا |
| Strict-Transport-Security | اجبار استفاده از HTTPS | بسیار بالا |
| X-Content-Type-Options | جلوگیری از MIME Sniffing | بالا |
| X-Frame-Options | کاهش ریسک Clickjacking | بالا |
| Referrer-Policy | کنترل اطلاعات Referrer | بالا |
| Permissions-Policy | محدود کردن قابلیتهای مرورگر | متوسط |
| COOP | جداسازی Browsing Context | وابسته به معماری |
| CORP | کنترل دسترسی Cross-Origin به منابع | وابسته به معماری |
| COEP | کنترل Embedding منابع Cross-Origin | وابسته به معماری |
این دستهبندی باید متناسب با نوع سایت و نیازهای فنی آن تفسیر شود. MDN نیز بر این نکته تأکید دارد که تهدیدها و راهکارهای امنیتی وب به نوع سایت و معماری آن وابسته هستند.
Security Headers یکی از لایههای مهم دفاع در معماری امنیت وب هستند. آنها با کنترل رفتار مرورگر میتوانند سطح حمله را کاهش دهند، اجرای منابع را محدود کنند، استفاده از HTTPS را اجباری کنند و جلوی برخی سناریوهای Clickjacking، MIME Sniffing و XSS را بگیرند.
اما ارزش واقعی این هدرها زمانی مشخص میشود که بهصورت Policy مبتنی بر معماری سایت پیادهسازی شوند. برای یک سایت ساده ممکن است چند Header پایه کافی باشد، در حالی که یک وباپلیکیشن بزرگ به CSP دقیق، کنترل Cross-Origin، سیاستهای Permission و مدیریت منابع شخص ثالث نیاز دارد.
در چنین شرایطی، امنیت موفق به معنای داشتن بیشترین Header نیست، بلکه به معنای داشتن Headerهای درست با مقادیر درست و بدون ایجاد اختلال در عملکرد سایت است.