پرش به محتوای اصلی
آسیب‌پذیری‌های سایت

Host Header Injection چیست؟ بررسی حملات HTTP Host Header و روش‌های جلوگیری

Host Header Injection زمانی ایجاد می‌شود که وب‌سایت یا زیرساخت HTTP مقدار Host یا Authority ارسال‌شده توسط Client را بدون اعتبارسنجی کافی قابل اعتماد فرض کند. این ضعف می‌تواند باعث Redirect ناخواسته، Web Cache Poisoning، دستکاری لینک‌های بازیابی رمز عبور یا Routing به Virtual Host اشتباه شود. استفاده از Allowlist دامنه‌ها، رد کردن Hostهای ناشناخته، ساخت URLهای حساس براساس Base URL ثابت و مدیریت صحیح Trusted Proxy و Forwarded Headerها از مهم‌ترین روش‌های جلوگیری از Host Header Injection هستند.

تیم امنیت رخنه‌کاو ۳۹ دقیقه مطالعه انتشار:

Host Header Injection یا تزریق هدر Host نوعی آسیب‌پذیری امنیتی در وب‌سایت‌ها و زیرساخت‌های HTTP است که زمانی ایجاد می‌شود که وب‌سرور، Reverse Proxy، CDN یا خود Application مقدار Host دریافت‌شده از Client را بدون اعتبارسنجی کافی به‌عنوان یک داده قابل‌اعتماد استفاده کند. این اعتماد می‌تواند باعث ساخت Redirect یا لینک اشتباه، آلوده شدن Cache، ایجاد لینک بازیابی رمز عبور با دامنه نادرست، Routing درخواست به Virtual Host ناخواسته یا افشای سرویس‌های داخلی شود.

مهم‌ترین روش جلوگیری از Host Header Injection این است که Host را داده قابل‌اعتماد فرض نکنیم. دامنه‌های مجاز باید با Allowlist مشخص شوند، Hostهای ناشناخته در اولین لایه ممکن Reject شوند، URLهای امنیتی مانند Password Reset براساس Base URL ثابت و Server-Side ساخته شوند و Headerهایی مانند X-Forwarded-Host و Forwarded فقط زمانی قابل اعتماد باشند که توسط Reverse Proxy مورد اعتماد بازنویسی و کنترل شوند.

HTTP Host Header چیست؟

برای درک Host Header Injection ابتدا باید بدانیم هدر Host چه نقشی در HTTP دارد.

یک IP Address می‌تواند هم‌زمان میزبان چندین وب‌سایت باشد.

فرض کنید یک Server با IP واحد، سه دامنه مختلف را میزبانی می‌کند:

example-a.com
example-b.com
example-c.com

زمانی که Request به Server می‌رسد، Web Server باید بفهمد درخواست مربوط به کدام سایت است.

در HTTP/1.1 این اطلاعات معمولاً از Header زیر به دست می‌آید:

Host: example-a.com

RFC 9110 توضیح می‌دهد که فیلد Host شامل اطلاعات Host و Port مربوط به Target URI است و به Origin Server اجازه می‌دهد هنگام سرویس‌دهی به چند Host Name، Resource صحیح را انتخاب کند. در HTTP/2 و HTTP/3 نیز این نقش در بعضی شرایط توسط pseudo-header به نام :authority انجام می‌شود.

بنابراین Host صرفاً یک Header تزئینی نیست.

این مقدار می‌تواند در تصمیم‌هایی مانند موارد زیر نقش داشته باشد:

انتخاب Virtual Host
ساخت URL کامل
Redirect
Cache Key
تولید لینک Email
Routing در Reverse Proxy
تشخیص Tenant
انتخاب Backend

همین اهمیت باعث می‌شود استفاده ناامن از آن یک Attack Surface ایجاد کند.

چرا Client می‌تواند Host Header را تغییر دهد؟

مرورگر عادی معمولاً Host صحیح را براساس URL تولید می‌کند.

اما Server نباید نتیجه بگیرد که تمام Requestها حتماً توسط Browser استاندارد ساخته می‌شوند.

یک HTTP Client می‌تواند Headerهای Request را تحت شرایط مختلف کنترل کند.

بنابراین از دید Application، مقدار Host باید یک ورودی خارجی در نظر گرفته شود.

اصل امنیتی مشابه سایر Inputهاست:

HTTP Request
      ↓
Untrusted Data
      ↓
Validation
      ↓
Application

نباید طراحی این‌گونه باشد:

Host Header
     ↓
Trusted Domain
     ↓
Security-sensitive Operation

بدون اینکه مرحله Validation وجود داشته باشد.

RFC 9110 نیز اشاره می‌کند که Host و Port در Routing سطح Application اهمیت زیادی دارند و دقیقاً به همین دلیل می‌توانند هدف حملات مربوط به Cache Poisoning یا هدایت درخواست به مقصد ناخواسته قرار بگیرند.

Host Header Injection چیست؟

Host Header Injection زمانی رخ می‌دهد که سیستم مقدار Host کنترل‌شده توسط Request را در Context حساسی استفاده کند، بدون آنکه بررسی کند مقدار مذکور یکی از Hostهای مجاز Application است.

OWASP Web Security Testing Guide چند پیامد اصلی را برای این ضعف ذکر می‌کند:

هدایت Request به Virtual Host اشتباه، Redirect به Domain تحت کنترل مهاجم، Web Cache Poisoning، دستکاری Password Reset و در بعضی معماری‌ها دسترسی به Virtual Hostهایی که قرار نبوده از اینترنت قابل دسترس باشند.

بنابراین آسیب‌پذیری صرفاً به این معنی نیست که:

Host تغییر می‌کند.

تغییر Header به‌تنهایی Vulnerability نیست.

سؤال اصلی این است:

Application با Host تغییرکرده چه کاری انجام می‌دهد؟

اگر Host نامعتبر Reject شود، رفتار مناسب است.

اگر Host صرفاً برای Virtual Hosting کنترل‌شده استفاده شود و هیچ دامنه ناشناخته‌ای پذیرفته نشود، خطر کاهش می‌یابد.

اما اگر Host وارد:

Location Header
Email Link
Cache Entry
Generated URL
Backend Routing
Security Decision

شود، Impact ممکن است افزایش پیدا کند. Host Header Injection چگونه ایجاد می‌شود؟

Host Header Injection چگونه ایجاد می‌شود؟

ریشه اصلی مشکل معمولاً «اعتماد بیش از حد به اطلاعات Authority موجود در Request» است.

فرض کنید Application برای تولید Absolute URL چنین منطقی داشته باشد:

scheme + request.host + path

توسعه‌دهنده ممکن است تصور کند request.host همیشه Domain واقعی سایت است.

اما مقدار آن می‌تواند از Request یا Proxy Header مشتق شده باشد.

اگر Application بدون Allowlist آن را قبول کند، Domain خارجی می‌تواند وارد URL تولیدشده شود.

مدل آسیب‌پذیر:

Client
  ↓
Host Header
  ↓
Application
  ↓
Generated Absolute URL

مدل امن‌تر:

Configured Canonical Base URL
            ↓
       Application
            ↓
Generated Absolute URL

در عملیات امنیتی معمولاً دلیلی وجود ندارد که Base Domain سایت برای هر Request دوباره از Client پرسیده شود.

Virtual Host چیست؟

وب‌سرورها برای میزبانی چند سایت روی یک Server معمولاً از Virtual Host استفاده می‌کنند.

برای مثال Nginx می‌تواند چند server block داشته باشد که هرکدام server_name متفاوت دارند.

مستندات رسمی Nginx توضیح می‌دهند که هنگام انتخاب Name-Based Virtual Server، مقدار Host با server_nameهای تعریف‌شده مقایسه می‌شود. اگر هیچ Server Name تطبیق پیدا نکند، Nginx Request را به Default Server آن Port می‌فرستد.

این رفتار دلیل اهمیت پیکربندی Default Host است.

اگر Default Server همان Production Application اصلی باشد و Hostهای ناشناخته را نیز پردازش کند، لایه‌ای که می‌توانست Request را زودتر Reject کند از دست می‌رود.

تفاوت Virtual Hosting عادی با Host Header Injection

استفاده Web Server از Host برای انتخاب Virtual Host کاملاً طبیعی است.

این رفتار استاندارد HTTP است.

مشکل زمانی ایجاد می‌شود که:

Host ناشناخته پذیرفته شود،

Application آن را در خروجی بازتاب دهد،

برای تصمیم امنیتی استفاده شود،

یا به یک Backend حساس Route شود.

پس:

Host-based Routing

به‌خودی‌خود Vulnerability نیست.

اما:

Unvalidated Host-based Security Decision

می‌تواند Vulnerability باشد.

Host Header Injection در تولید URL

یکی از رایج‌ترین Anti-Patternها ساخت URL کامل از روی Host Request است.

فرض کنید Application می‌خواهد لینک زیر را ایجاد کند:

https://example.com/account

اما به‌جای داشتن Configuration ثابت، Domain را از Request می‌گیرد.

به‌صورت مفهومی:

"https://" + request_host + "/account"

اگر request_host بدون Validation استفاده شود، تمام Functionهایی که Absolute URL می‌سازند باید بررسی شوند.

این Functionها ممکن است در بخش‌های غیرمنتظره‌ای استفاده شوند:

Email،

Webhook،

PDF،

Notification،

Redirect،

Canonical URL،

OpenGraph Metadata.

بنابراین یافتن یک Host-dependent Function اغلب به معنی بررسی Data Flow گسترده‌تر است. Password Reset Poisoning چیست؟

Password Reset Poisoning چیست؟

یکی از مهم‌ترین پیامدهای Host Header Injection با Password Reset مرتبط است.

فرایند بازیابی Password معمولاً Token حساسی تولید می‌کند.

سپس Application لینکی مشابه این می‌سازد:

https://example.com/reset-password/<token>

اگر Domain این URL از Host Request گرفته شود و Host به‌درستی Validate نشود، Application ممکن است Link را با Domain نادرست تولید کند.

OWASP این سناریو را Password Reset Poisoning معرفی می‌کند و توضیح می‌دهد که در Application آسیب‌پذیر، Domain کنترل‌شده از Request ممکن است وارد Reset URL ارسال‌شده به User شود. در نتیجه Token حساس می‌تواند به مقصد اشتباه هدایت شود.

نکته مهم این است که مشکل اصلی Token Generator نیست.

ممکن است Token:

Random،

Long،

Cryptographically Secure،

Single Use

باشد.

اما اگر Destination لینک از Input کنترل‌شده ساخته شود، Security Boundary شکسته شده است.

راه امن ساخت Password Reset URL

Reset URL باید بر اساس Configuration مورد اعتماد ساخته شود.

مثلاً Application Configuration مشخص می‌کند:

PUBLIC_BASE_URL=https://example.com

سپس:

Configured Base URL
       +
Reset Path
       +
Secure Token

URL را می‌سازد.

نه اینکه Base Domain را از Request دریافت کند.

این اصل برای:

Email Verification،

Invite Link،

Magic Login Link،

Account Activation،

Payment Callback URL

نیز کاربرد دارد. Web Cache Poisoning و Host Header

Web Cache Poisoning و Host Header

Cache معمولاً Response را براساس Cache Key ذخیره می‌کند.

مشکل زمانی ایجاد می‌شود که Host روی Response اثر بگذارد ولی Cache Key آن Variation را به شکل صحیح در نظر نگیرد.

فرض کنید Application براساس Host یک URL داخل HTML تولید کند.

اگر Response سپس در Shared Cache ذخیره شود، امکان دارد Representation اشتباه برای Userهای دیگر Serve شود.

OWASP Host Header Injection را صراحتاً به‌عنوان یکی از مسیرهای Web Cache Poisoning معرفی می‌کند.

RFC 9110 نیز هشدار می‌دهد اطلاعات Host و Port به دلیل نقش آنها در Routing و Cache Key می‌توانند هدف Cache Poisoning قرار بگیرند.

راهکار فقط تنظیم Cache نیست.

Root Cause باید برطرف شود:

Response عمومی نباید براساس Host غیرمجاز تغییر کند.

Redirect Poisoning

بعضی Applicationها Request را از HTTP به HTTPS Redirect می‌کنند.

مثلاً:

http://example.com/page

به:

https://example.com/page

اگر Redirect Destination با Host Header خام ساخته شود، ممکن است Domain نامعتبر نیز وارد Location شود.

OWASP این حالت را یکی از پیامدهای Host Header Injection می‌داند.

روش امن‌تر این است که Redirect Host از Configuration یا Allowlist معتبر به دست آید.

Host Header و Open Redirect چه تفاوتی دارند؟

Open Redirect معمولاً زمانی رخ می‌دهد که User مستقیماً Destination URL یا بخشی از آن را کنترل می‌کند.

مثلاً:

?next=https://...

در Host Header Injection، منبع Domain ممکن است Host Request باشد.

نتیجه نهایی هر دو می‌تواند Redirect ناخواسته باشد، اما Root Cause متفاوت است.

در گزارش Security باید مشخص شود مشکل از چه Inputی ایجاد شده است.

دسترسی به Virtual Hostهای داخلی

در بعضی Architectureها چند Virtual Host روی یک Server یا Load Balancer قرار دارند.

مثلاً:

www.example.com
admin-internal.example.com
monitoring.example.com

ممکن است DNS عمومی فقط www.example.com را Resolve کند.

اما اگر Public Server براساس Host Request بتواند Virtual Host دیگر را انتخاب کند، DNS به‌تنهایی Access Control محسوب نمی‌شود.

OWASP اشاره می‌کند که Host Header Manipulation در برخی شرایط می‌تواند Virtual Hostهایی را قابل دسترس کند که برای External Access طراحی نشده‌اند.

این نکته یک اصل مهم معماری را نشان می‌دهد:

عدم وجود Public DNS Record
≠
Access Control

سرویس داخلی باید Authentication، Network Restriction و Routing Policy مستقل داشته باشد.

Default Virtual Host چه خطری دارد؟

وقتی Host با هیچ Virtual Host مشخصی تطبیق نداشته باشد، Web Server باید تصمیم بگیرد Request کجا برود.

در Nginx معمولاً Default Server برای آن Address/Port انتخاب می‌شود. اگر default_server صریح تعیین نشده باشد، اولین Server Block می‌تواند نقش Default را داشته باشد.

از دید امنیتی بهتر است Default Host یک Catch-All امن باشد.

مثلاً:

Unknown Host
     ↓
Reject

نه:

Unknown Host
     ↓
Main Production App

این اصل Attack Surface مرتبط با Hostهای ناشناخته را کاهش می‌دهد.

HTTP/2 و :authority

Host Header Injection را نباید فقط مسئله HTTP/1.1 بدانیم.

در HTTP/2 و HTTP/3 مفهوم Authority همچنان وجود دارد.

RFC 9110 می‌گوید Host در برخی موارد توسط pseudo-header با نام :authority جایگزین می‌شود.

در معماری‌هایی که:

HTTP/2
   ↓
CDN
   ↓
Reverse Proxy
   ↓
HTTP/1.1 Backend

وجود دارد، باید بررسی شود Authority چگونه بین لایه‌ها Transform می‌شود.

ممکن است Proxy مقدار را:

Normalize،

Replace،

Forward

کند.

Security Policy باید روی یک Source مشخص و Trusted تعریف شود. X-Forwarded-Host چیست و چه خطری دارد؟

X-Forwarded-Host چیست؟

Reverse Proxyها گاهی Host اصلی درخواست را در Headerهایی مثل:

X-Forwarded-Host

به Backend منتقل می‌کنند.

این Header می‌تواند برای Application مفید باشد.

مثلاً Public Domain:

shop.example.com

ممکن است روی Backend داخلی به:

app:8080

Proxy شود.

Backend اگر فقط Host داخلی را ببیند، برای ساخت URL عمومی نیاز به دانستن Host اصلی دارد.

اینجا X-Forwarded-Host وارد معماری می‌شود.

اما یک خطر مهم وجود دارد:

Application نباید هر X-Forwarded-Hostای که Client ارسال کرده است را Trusted در نظر بگیرد.

خطر Trust کردن X-Forwarded-Host

OWASP در راهنمای Host Header Injection اشاره می‌کند که سیستم‌هایی که Host اصلی را Validate می‌کنند ولی Headerهای Forwarded را بدون کنترل مصرف می‌کنند، ممکن است همچنان در معرض Host-related Attack باشند.

بنابراین Architecture صحیح باید چنین باشد:

Internet Client
     ↓
Trusted Reverse Proxy
     ↓
Remove / overwrite forwarded headers
     ↓
Backend

نه:

Internet Client
     ↓
Supplied X-Forwarded-Host
     ↓
Backend trusts it

Proxy باید Incoming Forwarded Headerهای خارجی را حذف یا بازنویسی کند.

Forwarded Header چیست؟

استانداردهای HTTP همچنین Header استاندارد Forwarded را برای انتقال اطلاعات Proxy معرفی کرده‌اند.

اما از دید امنیتی اصل تغییر نمی‌کند:

Forwarded Metadata فقط زمانی قابل اعتماد است که:

مسیر Proxy قابل کنترل باشد،

Backend مستقیماً از اینترنت قابل دسترس نباشد،

و Proxy Headerها را خودش تولید یا Sanitize کند.

وجود یک Header استاندارد آن را Trusted نمی‌کند.

Trusted Proxy چیست؟

بعضی Frameworkها تنظیمی دارند که مشخص می‌کند کدام Proxyها Trusted هستند.

این تنظیم اهمیت زیادی دارد.

اگر Application تمام Sourceها را Trusted Proxy بداند، Client ممکن است Headerهای Forwarded را مستقیماً تعیین کند.

در یک Architecture صحیح:

Only known load balancer IPs

باید در Trust List قرار گیرند.

نه:

Trust every proxy

مگر اینکه Architecture واقعاً دلیل مستندی برای آن داشته باشد.

Host Header Injection و Reverse Proxy

در Infrastructure مدرن معمولاً Request چند Layer را طی می‌کند:

Browser
   ↓
CDN
   ↓
WAF
   ↓
Load Balancer
   ↓
Reverse Proxy
   ↓
Application Server

هر Layer ممکن است:

Host را حفظ کند،

تغییر دهد،

یا Header جدیدی اضافه کند.

بنابراین فقط بررسی Application Code کافی نیست.

باید End-to-End مشخص شود:

Host اصلی چیست؟

کدام Layer آن را Validate می‌کند؟

Backend کدام Header را می‌خواند؟

چه Hostهایی مجازند؟

Unknown Host کجا Reject می‌شود؟

تفاوت Host Header Injection با SSRF

Host Header Injection و Server-Side Request Forgery یا SSRF گاهی به‌دلیل موضوع Host و Destination با هم اشتباه گرفته می‌شوند.

در SSRF، Server به مقصدی که User روی آن اثر دارد Request ارسال می‌کند.

در Host Header Injection، User روی Authority مربوط به HTTP Request فعلی یا URLهای تولیدشده Application اثر می‌گذارد.

ویژگیHost Header InjectionSSRF
ورودی اصلیHost/Authority مرتبط با RequestURL یا Destination درخواست Server-Side
رفتار اصلیRouting، URL Generation، Redirect، CacheServer Request به مقصد دیگر
Request جدید از Server ضروری است؟خیرمعمولاً بله
Password Reset Poisoningممکن استسناریوی اصلی نیست
Internal Service Accessدر بعضی Virtual Hostهایکی از Impactهای شناخته‌شده
کنترل اصلیHost Allowlist و Trusted ProxyURL/Network Validation و Egress Control

ممکن است یک Application هر دو مشکل را داشته باشد، اما این دو Vulnerability نباید یکی در نظر گرفته شوند.

تفاوت Host Header Injection با HTTP Request Smuggling

Request Smuggling معمولاً از اختلاف Parsing پیام HTTP بین Frontend و Backend استفاده می‌کند.

مثلاً دو Component درباره مرز Requestها توافق ندارند.

در Host Header Injection مشکل اصلی Trust کردن Authority یا Host نامعتبر است.

بنابراین:

Request Smuggling
→ Message Framing / Parser Disagreement

در مقابل:

Host Header Injection
→ Authority Validation / Trust

است.

OWASP نیز Request Smuggling را جداگانه در تست‌های HTTP Protocol بررسی می‌کند.

تفاوت Host Header Injection با HTTP Response Splitting

Response Splitting عمدتاً زمانی ایجاد می‌شود که Characterهای CR/LF کنترل‌شده وارد Response Header شوند.

این ضعف معمولاً با CWE-113 مرتبط است.

MITRE برای جلوگیری از آن Accept-Known-Good Validation و عدم استفاده از Input خام در HTTP Headerها را توصیه می‌کند.

در Host Header Injection لزوماً CRLF وجود ندارد.

ممکن است Host از نظر Syntax کاملاً Domain معتبری باشد ولی از نظر Application غیرمجاز باشد.

این تفاوت مثال خوبی برای اهمیت Semantic Validation است.

Host معتبر از نظر Syntax ممکن است از نظر Business نامعتبر باشد

فرض کنید Application فقط روی این Domainها سرویس می‌دهد:

example.com
www.example.com

مقدار:

other-example.net

می‌تواند از نظر DNS Name کاملاً معتبر باشد.

اما برای Application نامعتبر است.

بنابراین Validation نباید فقط سؤال کند:

آیا Host از نظر Syntax معتبر است؟

باید سؤال کند:

آیا Host یکی از Authorityهای مجاز این Application است؟

این همان تفاوت میان Syntax Validation و Allowlist Validation است.

Regex عمومی برای Host کافی نیست

یک Regular Expression که صرفاً Domain Format را Validate می‌کند، مشکل را از ریشه حل نمی‌کند.

مثلاً Regex می‌تواند تأیید کند ورودی شامل Characterهای مجاز Domain است.

اما همچنان هزاران Domain خارجی از نظر Syntax صحیح خواهند بود.

برای Applicationی با تعداد مشخص Domain، Allowlist روشن‌تر است:

example.com
www.example.com
api.example.com

هر مقدار دیگر Reject شود.

Subdomainهای پویا

بعضی SaaSها واقعاً Subdomain Dynamic دارند.

مثلاً:

tenant-a.example.com
tenant-b.example.com

در این شرایط Allowlist Exact برای تمام Tenantها ممکن است عملی نباشد.

اما همچنان نباید هر Domain پذیرفته شود.

Validation می‌تواند براساس:

Suffix معتبر،

Tenant Registry،

Database Mapping،

و وضعیت فعال Tenant

انجام شود.

مثلاً فقط Hostی معتبر باشد که:

*.example.com

است و Tenant Prefix آن در Registry وجود دارد.

صرف endsWith("example.com") نیز باید با دقت پیاده شود تا Domainهای مشابه اشتباه پذیرفته نشوند.

Host Header و Port

طبق RFC، Host می‌تواند Port نیز داشته باشد. ساختار آن به‌صورت Host به‌همراه Port اختیاری تعریف می‌شود.

بنابراین Validation باید درباره Port نیز تصمیم مشخصی داشته باشد.

مثلاً:

example.com
example.com:443

ممکن است بسته به Architecture هر دو معتبر باشند.

اما Application نباید Arbitrary Port را صرفاً به‌دلیل درست بودن Host Name قبول و در Redirect یا Generated URL استفاده کند.

Canonicalization قبل از Validation اهمیت دارد.

Case Sensitivity

Domain Name از نظر معمول Matching باید به شکل مناسبی Normalize شود.

RFC 9110 در تعریف Origin اشاره می‌کند Scheme و Host برای Normalization به Lowercase تبدیل می‌شوند.

بنابراین Allowlist نباید با Comparison اشتباه Case-Sensitive قابل دور زدن باشد.

MITRE نیز نمونه‌هایی از Vulnerabilityهای واقعی دارد که Validation Host به دلیل مقایسه Case-Sensitive قابل دور زدن بوده است.

Trailing Dot و Canonicalization

Domain ممکن است در بعضی Contextها با نمایش‌های معادل متفاوت دیده شود.

این موضوع یادآور اصل کلی است:

Security Check باید Representation مورد استفاده Stack را بشناسد.

Application نباید مجموعه‌ای از Replaceهای تصادفی انجام دهد.

بهتر است URL/Host Parsing با API استاندارد Platform انجام شود و سپس Host Canonical با Allowlist مقایسه شود.

Host Header Injection در Nginx

Nginx از server_name برای انتخاب Server Block استفاده می‌کند.

مستندات رسمی Nginx توضیح می‌دهند اگر Host با هیچ Server Name تطبیق نداشته باشد، Request به Default Server آن Port می‌رود.

بنابراین یکی از Hardeningهای مهم ایجاد Default Server صریح برای Hostهای ناشناخته است.

مدل معماری مناسب:

Internet
   ↓
Nginx
   ├── known-domain-1 → Application
   ├── known-domain-2 → Application
   └── everything else → Reject

به این ترتیب Request با Domain نامعتبر قبل از رسیدن به Application متوقف می‌شود.

آیا server_name _; به‌تنهایی کنترل امنیتی کامل است؟

خیر.

در Nginx _ یک نام قراردادی است که اغلب در Catch-All Configuration دیده می‌شود، اما رفتار Default Server در اصل به listen ... default_server مربوط است، نه اینکه _ به‌صورت جادویی تمام Hostها را Match کند.

بنابراین Configuration باید آگاهانه طراحی شود.

هدف این است که Server Block پیش‌فرض Requestهای ناشناخته را پردازش نکند.

Apache و Host Header

Apache نیز برای Name-Based Virtual Hosting از Host Information استفاده می‌کند.

Directiveهایی مانند ServerName و UseCanonicalName می‌توانند روی نحوه ساخت Self-Referential URLها اثر بگذارند.

مستندات Apache توضیح می‌دهند وقتی UseCanonicalName On باشد، Server برای URLهای Self-Referential از Hostname و Port موجود در ServerName استفاده می‌کند؛ در حالت Off، اطلاعات ارائه‌شده توسط Client می‌تواند در ساخت چنین URLهایی دخیل باشد.

بنابراین Applicationهای Apache نیز باید بررسی شوند که:

URLهای Absolute از چه Sourceای ساخته می‌شوند،

Hostهای ناشناخته چگونه مدیریت می‌شوند،

و Reverse Proxy چه Headerهایی را Forward می‌کند. Host Header Injection در WordPress

Host Header Injection در WordPress

WordPress به‌صورت عادی home_url() و site_url() را براساس URLهای Configurationشده سایت تولید می‌کند.

مستندات رسمی WordPress نشان می‌دهند home_url() مقدار home را برمی‌گرداند و site_url() نیز از site_url تنظیم‌شده استفاده می‌کند.

این رفتار از ساخت دستی URL براساس Host Request مطمئن‌تر است.

مشکل معمولاً زمانی ایجاد می‌شود که Custom Code، Plugin، Theme یا Configuration سفارشی مستقیماً از:

$_SERVER['HTTP_HOST']

برای تولید URL استفاده کند.

خطر استفاده از HTTP_HOST در wp-config.php

در اینترنت نمونه‌هایی وجود دارند که WP_HOME یا WP_SITEURL را به‌صورت Dynamic براساس $_SERVER['HTTP_HOST'] تنظیم می‌کنند.

این روش باید با احتیاط بسیار زیادی بررسی شود.

خود مستندات WordPress توضیح می‌دهند که HTTP_HOST توسط PHP براساس HTTP Host Header Request ساخته می‌شود و بنابراین Dynamic Configuration مبتنی بر آن می‌تواند مشکل امنیتی ایجاد کند.

راه امن‌تر برای سایتی با Domain ثابت:

WP_HOME → configured trusted URL
WP_SITEURL → configured trusted URL

است.

نه Domainای که از هر Request استخراج شود.

WordPress Multisite

در Multisite شرایط پیچیده‌تر می‌شود، چون Domain Mapping ممکن است واقعاً Dynamic باشد.

در این حالت راهکار صحیح حذف تمام Host-based Logic نیست.

Host باید با Site Registry معتبر تطبیق داده شود.

یعنی Application بررسی کند Domain درخواست‌شده واقعاً مربوط به یک Site ثبت‌شده و فعال در Network است.

Unknown Host نباید آزادانه به Site پیش‌فرض Resolve شود مگر اینکه این رفتار آگاهانه و امن طراحی شده باشد.

Pluginهای WordPress

Pluginهای سفارشی از نقاط مهم Code Review هستند.

به‌خصوص Pluginهایی که:

Password Reset،

Email Verification،

Invite Link،

Payment،

Webhook،

REST API،

Redirect،

Canonical URL

تولید می‌کنند.

در Code Review باید جست‌وجو شود آیا URL به‌صورت دستی با HTTP_HOST ساخته شده است یا خیر.

وجود HTTP_HOST به‌تنهایی Vulnerability را ثابت نمی‌کند.

Data Flow و Context باید بررسی شوند.

REST API و Host Header

REST API ممکن است Absolute Linkهایی برای Pagination، Resource یا Callback ایجاد کند.

اگر Domain این Linkها از Request Authority گرفته شود، رفتار باید بررسی شود.

API بهتر است برای Public Base URL Configuration مشخص داشته باشد یا Framework را به‌گونه‌ای تنظیم کند که فقط Hostهای Trusted را بپذیرد.

GraphQL

GraphQL نیز از این مسئله مستثنی نیست.

ممکن است Resolverها یا Middlewareها Absolute URL تولید کنند.

Host Validation باید در Layer مشترک انجام شود، نه اینکه هر Resolver به‌طور مستقل تصمیم بگیرد.

Host Header و CORS

CORS و Host Validation مسائل متفاوتی هستند.

CORS عمدتاً کنترل می‌کند Browser چه Originهایی اجازه خواندن Response را دارند.

Host مشخص می‌کند Request به کدام Authority هدف گرفته شده است.

قرار دادن Domain در CORS Allowlist جای Host Allowlist را نمی‌گیرد.

همچنین Host Allowlist نیز جای CORS را نمی‌گیرد.

Host Header و CSRF

در بعضی CSRF Defenseها Host یا X-Forwarded-Host برای تشخیص Target Origin استفاده می‌شود.

OWASP CSRF Prevention Cheat Sheet توضیح می‌دهد که در معماری پشت Proxy، X-Forwarded-Host می‌تواند Host اصلی Request را منتقل کند؛ اما این طراحی فقط وقتی قابل اعتماد است که Proxy مسیر Header را کنترل کند.

اگر Client بتواند مستقیماً X-Forwarded-Host مورد اعتماد Application را تعیین کند، ممکن است Security Check اشتباه عمل کند.

پس Trusted Proxy Configuration بخشی از CSRF Architecture نیز هست.

Host Header Injection چگونه به‌صورت امن شناسایی می‌شود؟

هدف تست دفاعی این است که مشخص شود Application Hostهای ناشناخته را Trust می‌کند یا خیر، نه اینکه Token واقعی User را سرقت کنیم یا Cache Production را آلوده کنیم.

بهترین محیط تست Staging یا Environment کنترل‌شده است.

مرحله اول: معماری را بشناسید

قبل از Test مشخص کنید:

Request از چه Layerهایی عبور می‌کند؟

CDN وجود دارد؟

Reverse Proxy چیست؟

TLS کجا Terminate می‌شود؟

Backend چه Hostی می‌بیند؟

Forwarded Headerها چگونه ساخته می‌شوند؟

مرحله دوم: Allowed Hostها را مشخص کنید

مثلاً Application ممکن است فقط این Hostها را داشته باشد:

example.com
www.example.com
api.example.com

رفتار مورد انتظار برای هر Host مشخص شود.

همچنین رفتار Unknown Host تعریف شود:

Reject

مرحله سوم: Host ناشناخته آزمایشی

در محیط مجاز می‌توان Domain آزمایشی و بی‌خطر را جایگزین Host کرد و فقط Response را مشاهده کرد.

نباید از Domain واقعی شخص ثالث استفاده کرد.

مواردی که باید بررسی شوند:

Response Status،

Location Header،

HTML Linkها،

Canonical URL،

OpenGraph URL،

Cookie Domain،

Generated Email در Mail Sandbox.

اگر Host ناشناخته صرفاً Reject شود، رفتار مطلوب است.

مرحله چهارم: Proxy Headerها

در Staging بررسی شود آیا Headerهایی مثل:

X-Forwarded-Host
Forwarded

توسط Client قابل اثرگذاری هستند یا Proxy آنها را بازنویسی می‌کند.

هدف فقط مشخص کردن Trust Boundary است.

مرحله پنجم: Cache

برای تست Cache Poisoning از Production Userها یا Shared Cache واقعی استفاده نکنید.

Test باید در Cache Namespace جدا، Staging یا Requestهای نشانه‌گذاری‌شده انجام شود.

هدف بررسی این است که آیا Response Host-dependent است و Cache Key آن Variation را صحیح مدیریت می‌کند.

Code Review برای Host Header Injection

در Source Code باید نقاط مصرف Authority پیدا شوند.

عبارت‌های مورد بررسی بسته به زبان متفاوت‌اند، اما از نظر مفهومی Sourceها عبارت‌اند از:

request.host
HTTP_HOST
host header
X-Forwarded-Host
Forwarded
authority

Sinkهای مهم:

redirect()
absolute URL builder
password reset link
email verification
canonical URL
webhook URL
cache key
tenant selector
backend router

سپس Data Flow بررسی می‌شود:

Untrusted Authority
       ↓
Validation?
       ↓
Sensitive Sink

اگر Validation وجود ندارد، Finding باید دقیق‌تر بررسی شود.

SAST

SAST می‌تواند برخی Patternهای ساده را پیدا کند.

مثلاً:

HTTP_HOST
   ↓
String concatenation
   ↓
Location header

اما Host Header Injection اغلب Configuration و Infrastructure نیز دارد.

بنابراین Code Scan به‌تنهایی کافی نیست.

DAST

DAST برای این مسئله مفید است، چون Behavior واقعی Web Stack را می‌بیند.

اما Scanner باید در محیط کنترل‌شده استفاده شود.

فعال کردن Testهای Cache Poisoning یا Password Reset روی Production ممکن است Side Effect داشته باشد. چگونه از Host Header Injection جلوگیری کنیم؟

چگونه از Host Header Injection جلوگیری کنیم؟

بهترین دفاع ترکیبی از Infrastructure Validation و Application Design است.

Allowlist دامنه‌های مجاز

سیستم باید بداند چه Hostهایی معتبرند.

مثلاً:

example.com
www.example.com
api.example.com

Unknown Host باید Reject شود.

برای SaaS چند Tenant نیز Host باید با Registry واقعی Tenantها تطبیق داده شود.

Host را در اولین Layer ممکن Reject کنید

اگر Nginx، Load Balancer یا CDN می‌تواند Unknown Host را متوقف کند، Request لازم نیست تا Application برسد.

Defense in Depth می‌تواند چنین باشد:

CDN
 ↓ Validate host
Load Balancer
 ↓ Validate host
Reverse Proxy
 ↓ Known virtual host
Application
 ↓ Framework allowed-host validation
Business Logic

وجود چند Layer احتمال Configuration Mistake را کاهش می‌دهد.

Base URL را Config کنید

برای Functionهای امنیتی، Base URL باید Server-Side Configuration باشد.

مثلاً:

PUBLIC_BASE_URL
PASSWORD_RESET_BASE_URL
APP_URL

این مقادیر از Environment یا Configuration امن می‌آیند.

Request Host نباید آنها را تعیین کند.

Absolute URL فقط زمانی بسازید که لازم است

بسیاری از Responseها نیازی به Absolute URL ندارند.

برای Redirect داخل همان Site می‌توان در بعضی Frameworkها Relative Path استفاده کرد.

مثلاً:

/account

به‌جای ساخت دستی:

https://<request-host>/account

کاهش Dependency روی Request Authority Attack Surface را کم می‌کند.

البته رفتار دقیق به Framework و Protocol بستگی دارد.

Trusted Proxyها را دقیق تنظیم کنید

Backend باید بداند کدام IP یا Network واقعاً Reverse Proxy مورد اعتماد است.

Forwarded Headerها فقط از همان مسیر پذیرفته شوند.

Client نباید بتواند مستقیماً Headerهای Security-Relevant را تعیین کند.

در Edge Proxy بهتر است Headerهای ورودی مشابه حذف و سپس مقادیر استاندارد جدید اضافه شوند.

X-Forwarded-Host را کورکورانه Trust نکنید

وجود X-Forwarded-Host به معنی معتبر بودن آن نیست.

Backend باید مطمئن باشد:

Header توسط Proxy مورد اعتماد ساخته شده،

Client Original Header حذف شده،

و مقدار Forwarded Host نیز در Allowlist قرار دارد.

Catch-All امن بسازید

برای Nginx یا سایر Reverse Proxyها، Unknown Host باید به یک Default Virtual Host امن برسد.

این Default Host می‌تواند فقط Error مناسب برگرداند و هیچ Application Sensitiveای را Serve نکند.

Nginx مستند کرده است که Default Server برای Requestهایی که با هیچ server_name تطبیق ندارند استفاده می‌شود.

Redirectها را Canonical کنید

اگر سیاست سایت این است که:

www.example.com

به:

example.com

Redirect شود، Destination باید Canonical Domain ثابت باشد.

نه اینکه Host Request دوباره در Redirect استفاده شود.

Cache Key را بررسی کنید

اگر Application واقعاً چند Host را پشتیبانی می‌کند، Cache باید Host/Authority را به شکل صحیح در Cache Key لحاظ کند.

در کنار آن باید بررسی شود Response یک Host هیچ‌گاه برای Host دیگر Serve نمی‌شود.

اما اضافه کردن Host به Cache Key جای Validation Unknown Host را نمی‌گیرد.

Password Reset را مستقل از Host طراحی کنید

Reset Link باید از Config ثابت ساخته شود.

Token باید:

Random،

Expireable،

Single Use،

و مرتبط با Account صحیح

باشد.

ولی حتی بهترین Token نیز Host Poisoning را جبران نمی‌کند.

Security تمام اجزای Flow را نیاز دارد.

Webhook Callbackها

گاهی Application Callback URL خودش را به Third Party اعلام می‌کند.

اگر Callback Domain از Host Request ساخته شود، ممکن است Configuration اشتباه ایجاد شود.

Callback URL نیز بهتر است Configured Value باشد.

Canonical و OpenGraph URLها

Host Header Injection همیشه Account Takeover ایجاد نمی‌کند.

گاهی فقط:

Canonical Tag،

OpenGraph URL،

Asset URL

تحت تأثیر قرار می‌گیرند.

Severity چنین مواردی باید براساس Impact واقعی ارزیابی شود.

وجود Host Reflection به‌تنهایی نباید بدون Evidence به‌عنوان Critical Vulnerability گزارش شود.

Logging و Monitoring

Hostهای نامعتبر باید قابل مشاهده باشند.

می‌توان Security Eventهایی مانند:

Unknown Host
Unexpected Forwarded Host
Host / SNI mismatch
Invalid Authority

را Log کرد.

Spike در Unknown Host ممکن است نشانه Scanning یا Misconfiguration باشد.

Log نباید Secretهای دیگر Request را بی‌دلیل ذخیره کند.

SNI و Host

در HTTPS، TLS Server Name Indication یا SNI نیز نام Domain موردنظر Client را قبل از HTTP Request منتقل می‌کند.

SNI و Host دو Layer متفاوت‌اند.

در بسیاری از شرایط باید با یکدیگر سازگار باشند.

اما Application نباید فقط به این دلیل که TLS Connection برای Certificate معتبری برقرار شده، هر Host Header بعدی را Trusted فرض کند.

TLS Authentication، Host Validation و Application Routing باید هماهنگ باشند.

معماری Cloud و Host Header

در Cloud ممکن است چند Layer مانند:

CDN،

Application Load Balancer،

Ingress Controller،

Service Mesh

وجود داشته باشند.

هر Layer Ruleهای Host خودش را دارد.

یکی از مشکلات رایج این است که Edge فقط Domain مشخص را می‌پذیرد اما Backend Service مستقیماً از اینترنت نیز قابل دسترس است.

در چنین حالتی Attack Surface اصلی Validation Edge دور زده می‌شود.

Backend Origin بهتر است فقط از Edge مورد اعتماد Connection بپذیرد.

Kubernetes Ingress

در Kubernetes معمولاً Ingress Ruleها براساس Host تعریف می‌شوند.

اما همچنان باید:

Default Backend امن باشد،

Ingress Controller Updated باشد،

Service Backend مستقیماً Public نشود،

و Application نیز در صورت نیاز Allowed Host داشته باشد.

Infrastructure Routing نباید تنها خط دفاع باشد.

Multi-Tenant SaaS

در SaaS چندمستاجری Host ممکن است Tenant Identifier باشد.

مثلاً:

company-a.example.com
company-b.example.com

این طراحی قابل قبول است، به شرط آنکه:

Domain از Registry معتبر Resolve شود،

Tenant فعال باشد،

Authorization مستقل بررسی شود،

و Host خارجی Arbitrary پذیرفته نشود.

Host انتخاب Tenant نباید جای User Authorization را بگیرد.

دانستن Tenant Domain به معنی Permission دسترسی به داده Tenant نیست.

اشتباهات رایج در جلوگیری از Host Header Injection

فقط Validate کردن Format دامنه

Domain خارجی نیز Format معتبر دارد.

Allowlist لازم است.

Trust کردن هر X-Forwarded-Host

این Header فقط وقتی معتبر است که Proxy مورد اعتماد آن را کنترل کند.

استفاده از HTTP_HOST برای ساخت تمام URLها

برای سایت با Domain ثابت این کار معمولاً غیرضروری است.

از Base URL Configuration استفاده کنید.

Redirect Unknown Host به خودش

اگر Redirect مقصد براساس Host ناشناخته ساخته شود، Reject واقعی اتفاق نیفتاده است.

Unknown Host باید به Canonical Host ثابت Redirect شود یا کاملاً Reject شود.

اعتماد به DNS

اینکه فقط یک Domain به Server Resolve می‌شود به معنی Access Control نیست.

Request HTTP مستقیماً Authority خودش را حمل می‌کند.

پنهان کردن Backend بدون Firewall

اگر Backend Origin عمومی باشد، ممکن است Edge Host Validation قابل دور زدن شود.

استفاده از WAF به‌عنوان تنها دفاع

WAF می‌تواند برخی Patternها را متوقف کند، اما Host خارجی ممکن است از نظر Syntax کاملاً معتبر باشد.

Root Fix باید Allowlist و Secure Architecture باشد.

چک‌لیست دفاعی جلوگیری از Host Header Injection

کنترلسؤال امنیتی
Host Allowlistآیا فقط Domainهای مورد انتظار پذیرفته می‌شوند؟
Unknown Hostآیا Host ناشناخته قبل از Application Reject می‌شود؟
Default Virtual Hostآیا Catch-All امن و بدون Application حساس وجود دارد؟
Base URLآیا URLهای حساس از Config ثابت ساخته می‌شوند؟
Password Resetآیا Reset Link مستقل از Request Host است؟
Email Verificationآیا Domain لینک از Configuration می‌آید؟
Redirectآیا Location بر پایه Canonical Host ساخته می‌شود؟
Forwarded Headersآیا فقط Proxy مورد اعتماد آنها را تعیین می‌کند؟
X-Forwarded-Hostآیا Incoming Client Value حذف یا بازنویسی می‌شود؟
Trusted Proxyآیا فقط Proxyهای واقعی در Trust List هستند؟
HTTP/2آیا :authority نیز در Threat Model لحاظ شده است؟
Cacheآیا Host بخشی صحیح از Cache Isolation است؟
Virtual Hostsآیا سرویس‌های داخلی Access Control مستقل دارند؟
Backend Originآیا دسترسی مستقیم اینترنتی محدود شده است؟
SNI/Hostآیا Routing TLS و HTTP با Policy سازگار است؟
WordPressآیا URL با home_url()/site_url() یا Config معتبر ساخته می‌شود؟
HTTP_HOSTآیا استفاده مستقیم از آن در Plugin و Theme بررسی شده است؟
Loggingآیا Unknown Host و Authority نامعتبر ثبت می‌شوند؟
Testingآیا تست Host در Staging و بدون Side Effect انجام شده است؟
Regressionآیا Host Validation بعد از تغییر Proxy/CDN دوباره تست می‌شود؟

Host Header Injection در WordPress؛ چک‌لیست عملی

برای سایت‌های WordPress بهتر است ابتدا مقدار Home URL و Site URL مشخص و ثابت باشد.

توابع استاندارد:

home_url()
site_url()

در بسیاری از سناریوها باید به ساخت دستی URL ترجیح داده شوند، چون WordPress آنها را از تنظیمات Site استخراج می‌کند.

همچنین باید Plugin و Themeهای سفارشی برای موارد زیر بررسی شوند:

ساخت Reset Link سفارشی،

Invite Link،

Redirect سفارشی،

Webhook URL،

REST Response Link،

استفاده مستقیم از HTTP_HOST.

در wp-config.php نیز Dynamic Definition مبتنی بر $_SERVER['HTTP_HOST'] باید با حساسیت بررسی شود. مستندات رسمی WordPress صراحتاً یادآوری می‌کنند که HTTP_HOST از HTTP Host Header Request به دست می‌آید.

WAF چه کمکی می‌کند؟

WAF می‌تواند Hostهایی را که خارج از Policy هستند Reject کند.

این کنترل مفید است.

اما WAF نباید تنها مکان Validation باشد.

اگر WAF Bypass شود یا Backend Origin مستقیماً قابل دسترس باشد، مشکل دوباره ظاهر می‌شود.

Defense in Depth بهتر است:

Edge validation
+
Reverse proxy validation
+
Application allowed-host configuration
+
Safe URL generation

آیا HTTPS از Host Header Injection جلوگیری می‌کند؟

HTTPS به‌تنهایی خیر.

TLS از Confidentiality و Integrity ارتباط و Authentication Server نسبت به Authority موردنظر Client محافظت می‌کند.

اما Application همچنان باید Host/Authority دریافت‌شده را در Context خودش صحیح Validation کند.

RFC 9110 نیز Authority را بخش مهم Target URI می‌داند و درباره اهمیت بررسی آن در Routing هشدار می‌دهد.

HTTPS جای Allowed Host Policy را نمی‌گیرد.

Host Header Injection و HSTS

HSTS مرورگر را مجبور می‌کند Domain مشخص را از HTTPS استفاده کند.

اما Host Validation را انجام نمی‌دهد.

HSTS برای Downgrade Protection مفید است ولی علاج Host Header Injection نیست.

Host Header Injection و CSP

Content-Security-Policy نیز هدف متفاوتی دارد.

CSP می‌تواند بارگذاری Resourceها را محدود کند و در بعضی سناریوها Impact یک Response Poisoning را کاهش دهد، اما Root Cause Host Injection را اصلاح نمی‌کند.

Security Headerها مکمل‌اند، نه جایگزین Validation.

آیا Host Reflection همیشه Vulnerability است؟

خیر.

فرض کنید Debug Endpoint فقط Host دریافتی را به User فعلی نمایش دهد و هیچ Security Decision، Redirect، Cache یا Link حساسی به آن وابسته نباشد.

ممکن است Impact بسیار کم یا حتی غیرقابل‌استفاده باشد.

Finding باید براساس Sink ارزیابی شود.

سؤال‌ها:

Host کجا استفاده می‌شود؟

Response Cache می‌شود؟

آیا User دیگری Response را می‌بیند؟

Token وارد URL می‌شود؟

Redirect اتفاق می‌افتد؟

Routing داخلی تغییر می‌کند؟

بدون پاسخ به این سؤال‌ها Severity دقیق قابل تعیین نیست.

Severity چگونه تعیین می‌شود؟

Severity Host Header Injection از Informational تا Critical می‌تواند متفاوت باشد.

برای مثال:

Host صرفاً در یک Metadata غیرحساس Reflect می‌شود → Risk محدود.

Host باعث Redirect خارجی می‌شود → Context مهم است.

Host وارد Shared Cache می‌شود → دامنه Impact بیشتر.

Host وارد Reset Link حاوی Token می‌شود → امکان Account Compromise ممکن است ایجاد شود.

Host امکان دسترسی به Admin Virtual Host بدون Authorization دیگر می‌دهد → Severity می‌تواند بسیار بالا باشد.

بنابراین عنوان Vulnerability به تنهایی Severity را تعیین نمی‌کند.

چگونه گزارش Host Header Injection حرفه‌ای بنویسیم؟

گزارش باید بیشتر از عبارت:

Host Header Injection found.

اطلاعات داشته باشد.

باید مشخص شود:

Source کدام Header است؟

آیا Host یا Forwarded Host؟

کدام Component آن را Trust می‌کند؟

Host در کدام Sink استفاده می‌شود؟

چه Behaviorی به‌صورت ایمن اثبات شده؟

آیا Cache، Email یا Redirect تحت تأثیر است؟

Impact دقیق چیست؟

Remediation در کدام Layer باید انجام شود؟

مثلاً:

Root Cause:
Application constructs password reset absolute URLs
from an unvalidated request authority.

Expected:
Reset links use the configured public application origin.

Observed:
Changing the authority changes the generated link domain.

Recommended:
Build reset URLs from a fixed server-side base URL and
reject unknown hosts at the reverse proxy.

این گزارش برای Developer قابل اقدام است.

اگر Host Header Injection در Production پیدا شد چه کنیم؟

ابتدا مشخص کنید Sink چیست.

اگر فقط Redirect کم‌خطر است، Incident Scope با حالتی که Password Reset Token تحت تأثیر است متفاوت خواهد بود.

موارد بررسی:

Hostهای غیرعادی در Access Log،

Reset Requestهای مشکوک،

Cache Entryهای غیرعادی،

Forwarded Headerهای غیرمنتظره،

دسترسی به Virtual Hostهای داخلی،

و Requestهای مستقیم به Backend Origin.

سپس Host Allowlist و URL Generation اصلاح شوند.

اگر Token امنیتی احتمالاً افشا شده، Tokenهای فعال باید طبق Incident Response Policy باطل شوند.

اگر Cache Poisoning ممکن بوده، Cache نیز باید Purge و بررسی شود.

Regression Test پس از اصلاح

پس از Fix باید چند حالت آزمایش شود:

Host اصلی پذیرفته شود.

Host Alias مجاز پذیرفته شود.

Unknown Host رد شود.

HTTP/2 Authority نامعتبر رد شود.

Forwarded Host خارجی توسط Client اثر نگذارد.

Redirectها همیشه به Canonical Domain بروند.

Password Reset Domain ثابت بماند.

Cache بین Hostها Isolation صحیح داشته باشد.

آزمون باید پس از تغییر:

CDN،

Reverse Proxy،

Load Balancer،

Framework

نیز دوباره اجرا شود.

Defense in Depth

یک معماری مقاوم را می‌توان به این صورت تصور کرد:

Internet
   ↓
CDN / WAF
Host Allowlist
   ↓
Load Balancer
Known domains only
   ↓
Reverse Proxy
Sanitize forwarded headers
   ↓
Application
Allowed Hosts
   ↓
Security-sensitive features
Configured Base URLs

در این طراحی شکست یک کنترل الزاماً به Compromise کامل منجر نمی‌شود.

سؤالات متداول درباره Host Header Injection

Host Header Injection چیست؟

Host Header Injection زمانی ایجاد می‌شود که Application یا Infrastructure مقدار Host یا Authority کنترل‌شده توسط Request را بدون Validation کافی Trust کند. این ضعف می‌تواند Redirect، Cache، URL Generation، Password Reset یا Routing را تحت تأثیر قرار دهد.

Host Header در HTTP چیست؟

Host مشخص می‌کند Request برای کدام Host و Port هدف‌گذاری شده است و در Serverهایی که چند Domain را میزبانی می‌کنند برای انتخاب Virtual Host اهمیت دارد. RFC 9110 ساختار و نقش Host و :authority را تعریف می‌کند.

Host Header Injection چه خطراتی دارد؟

OWASP پیامدهایی مانند Redirect ناخواسته، Web Cache Poisoning، Password Reset Poisoning، Routing به Default Host و دسترسی به Virtual Hostهای غیرعمومی را مطرح می‌کند.

Password Reset Poisoning چیست؟

حالتی است که Domain یک Reset URL از Host غیرقابل‌اعتماد ساخته می‌شود. در نتیجه ممکن است لینک حاوی Reset Token به Domain اشتباه اشاره کند. OWASP این مورد را یکی از مهم‌ترین سناریوهای Host Header Injection معرفی می‌کند.

آیا تغییر Host Header به‌تنهایی Vulnerability است؟

خیر. Vulnerability زمانی معنا پیدا می‌کند که Host غیرمجاز توسط Server پذیرفته شود و به Behavior امنیتی قابل توجهی منجر شود.

بهترین روش جلوگیری از Host Header Injection چیست؟

استفاده از Allowlist دامنه‌های مجاز، Reject کردن Unknown Host، ساخت URLهای حساس از Base URL ثابت، تنظیم Trusted Proxy و عدم اعتماد مستقیم به Forwarded Headerها از مهم‌ترین راهکارها هستند.

آیا X-Forwarded-Host امن است؟

خود Header ذاتاً امن نیست. فقط اگر Reverse Proxy مورد اعتماد Incoming Header را کنترل و مقدار معتبر را خودش تنظیم کند، Backend می‌تواند براساس Configuration مشخص به آن اعتماد کند. OWASP نیز خطر Host Header Injection از طریق X-Forwarded-Host را مطرح می‌کند.

آیا HTTP/2 هم در معرض این مشکل است؟

بله. HTTP/2 و HTTP/3 مفهوم Authority را همچنان دارند و RFC 9110 توضیح می‌دهد که :authority در برخی موارد جای Host را می‌گیرد.

آیا HTTPS جلوی Host Header Injection را می‌گیرد؟

خیر. HTTPS ارتباط را امن می‌کند، اما Allowed Host Policy و نحوه استفاده Application از Authority مسئله جداگانه‌ای هستند.

آیا Nginx خودکار Host ناشناخته را Reject می‌کند؟

الزاماً خیر. مستندات Nginx می‌گویند اگر Host با server_name تطبیق پیدا نکند، Request به Default Server مربوط به آن Port می‌رود. بنابراین Default Server باید آگاهانه و امن تنظیم شود.

آیا WordPress در برابر Host Header Injection آسیب‌پذیر است؟

وجود WordPress به معنی Vulnerability نیست. WordPress توابعی مانند home_url() و site_url() را براساس URLهای تنظیم‌شده ارائه می‌کند. خطر بیشتر زمانی مطرح می‌شود که Custom Code یا Configuration مستقیماً $_SERVER['HTTP_HOST'] را Trust کند.

آیا HTTP_HOST در WordPress قابل اعتماد است؟

نباید بدون Validation به‌عنوان Source امنیتی ثابت در نظر گرفته شود. مستندات WordPress توضیح می‌دهند که HTTP_HOST از HTTP Host Header Request ساخته می‌شود و درباره استفاده Dynamic از آن هشدار داده‌اند.

Host Header Injection با SSRF چه فرقی دارد؟

در SSRF، Server یک Request جدید به Destination قابل‌کنترل ارسال می‌کند. در Host Header Injection، Authority Request فعلی یا URLهای تولیدشده Application تحت تأثیر قرار می‌گیرند.

Host Header Injection با Request Smuggling یکی است؟

خیر. Request Smuggling به اختلاف Parsing HTTP میان چند Component مرتبط است، درحالی‌که Host Header Injection به Validation و Trust Authority مربوط می‌شود.

آیا WAF برای جلوگیری از Host Header Injection کافی است؟

خیر. WAF کنترل مکمل است. Domain مهاجم ممکن است از نظر Syntax کاملاً معتبر باشد. Application و Reverse Proxy باید Allowed Hostها را مستقل enforce کنند.

آیا Cache می‌تواند تحت تأثیر Host Header Injection باشد؟

بله. اگر Host روی Response اثر بگذارد ولی Cache Key و Validation درست نباشند، Web Cache Poisoning ممکن است مطرح شود. OWASP و RFC 9110 هر دو به خطر Cache Poisoning مرتبط با Host اشاره می‌کنند.

جمع‌بندی

Host Header Injection نمونه‌ای مهم از آسیب‌پذیری‌هایی است که از اعتماد اشتباه به Metadata یک HTTP Request ایجاد می‌شوند.

هدر Host در HTTP/1.1 و مفهوم :authority در HTTP/2 و HTTP/3 برای مشخص کردن Authority درخواست و Routing اهمیت بنیادی دارند. RFC 9110 صراحتاً Host و Port را بخشی مهم از Target URI می‌داند و به خطر سوءاستفاده از آنها در Routing و Shared Cache اشاره می‌کند.

مشکل از آنجا آغاز می‌شود که Application فرض می‌کند Host همیشه Domain واقعی سایت است.

این فرض صحیح نیست.

Host بخشی از Request است و باید براساس معماری Application Validate شود.

اگر Host غیرقابل‌اعتماد وارد Redirect، Absolute URL، Password Reset Email، Cache Entry، Tenant Selection یا Backend Routing شود، پیامدهای مختلفی ایجاد می‌شوند.

OWASP از مهم‌ترین اثرات Host Header Injection به Password Reset Poisoning، Web Cache Poisoning، Redirect به Domain غیرمجاز، انتخاب Virtual Host ناخواسته و دسترسی احتمالی به Hostهای داخلی اشاره می‌کند.

بهترین دفاع حذف وابستگی غیرضروری به Request Host است.

برای URLهای حساس، Base Domain باید در Configuration سمت Server تعریف شود.

Password Reset، Account Verification، Magic Link، Webhook و سایر URLهای امنیتی نباید Domain خود را از Header کنترل‌شده توسط Client بگیرند.

در Edge و Reverse Proxy باید Allowed Hostها مشخص باشند و Unknown Hostها قبل از رسیدن به Application رد شوند.

Forwarded Headerهایی مانند X-Forwarded-Host نیز فقط در صورتی باید Trusted باشند که توسط Reverse Proxy مورد اعتماد حذف، بازنویسی و تولید شوند.

در Nginx باید Default Server آگاهانه تنظیم شود، زیرا مستندات رسمی نشان می‌دهند Requestهایی که Host آنها با هیچ server_name تطبیق ندارد به Default Server می‌روند.

در Apache نیز تنظیماتی مانند ServerName و UseCanonicalName باید با معماری URL Generation هماهنگ باشند؛ مستندات Apache توضیح می‌دهند که UseCanonicalName می‌تواند تعیین کند Server برای Self-Referential URL از ServerName ثابت یا اطلاعات Client استفاده کند.

در WordPress بهتر است URLهای داخلی با APIهایی مانند home_url() و site_url() و Configuration معتبر ساخته شوند. استفاده مستقیم از $_SERVER['HTTP_HOST'] در Plugin، Theme یا wp-config.php باید با حساسیت بررسی شود، زیرا خود WordPress نیز یادآوری می‌کند HTTP_HOST از Host Header درخواست مشتق می‌شود.

در نهایت، مهم‌ترین سؤال هنگام بررسی Host Header Injection این است:

«آیا این سیستم Host یا Authority دریافت‌شده از Client را فقط برای پردازش کنترل‌شده HTTP استفاده می‌کند، یا آن را به‌عنوان حقیقت قابل‌اعتماد درباره Domain، Routing یا یک عملیات امنیتی می‌پذیرد؟»

اگر پاسخ قسمت دوم باشد، Host Validation و معماری Trust Proxy باید با دقت بازبینی شوند.

مطالب مرتبط