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

Open Redirect چیست؟ بررسی آسیب‌پذیری ریدایرکت باز و خطرات آن

Open Redirect یا ریدایرکت باز زمانی ایجاد می‌شود که یک وب‌سایت مقصد انتقال کاربر را از داده قابل‌کنترل Client دریافت کند و بدون اعتبارسنجی کافی به همان مقصد Redirect شود. این ضعف می‌تواند برای Phishing استفاده شود و در بعضی سناریوها به بخشی از زنجیره حملات OAuth یا دور زدن کنترل‌های مبتنی بر Domain تبدیل شود. جلوگیری از دریافت URL Arbitrary، استفاده از Server-Side Mapping، Allowlist دقیق مقصدها و Validation صحیح Scheme و Host از مهم‌ترین روش‌های جلوگیری از Open Redirect هستند.

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

Open Redirect یا «ریدایرکت باز» نوعی آسیب‌پذیری امنیتی است که زمانی ایجاد می‌شود که یک وب‌سایت مقصد Redirect را از داده قابل‌کنترل توسط کاربر دریافت کند و بدون اعتبارسنجی کافی، مرورگر را به همان مقصد هدایت کند. در نتیجه ممکن است یک URL متعلق به دامنه معتبر سایت، کاربر را به یک دامنه غیرقابل‌اعتماد منتقل کند. این ضعف به‌تنهایی اغلب برای حملات Phishing استفاده می‌شود، اما خطر اصلی آن زمانی بیشتر می‌شود که به بخشی از زنجیره حمله OAuth، دور زدن بعضی Validationها، انتقال Credential یا هدایت کاربر از یک Context قابل‌اعتماد به مقصدی غیرقابل‌اعتماد تبدیل شود.

مهم‌ترین روش جلوگیری از Open Redirect این است که URL کامل و Arbitrary از User دریافت نشود. در صورت نیاز به Redirect پویا، بهتر است از شناسه یا مسیرهای داخلی از پیش تعریف‌شده استفاده شود و مقصد نهایی در Server تعیین گردد. اگر Redirect خارجی واقعاً ضروری است، Scheme، Host، Port و Destination باید با Allowlist دقیق بررسی شوند و مقایسه‌های ناقص مانند startsWith یا بررسی وجود نام دامنه در String نباید مبنای اعتماد باشند.

Redirect چیست و چرا در وب‌سایت‌ها استفاده می‌شود؟

Redirect یا URL Redirection یکی از قابلیت‌های عادی و ضروری وب است.

زمانی که Server می‌خواهد Browser به Resource دیگری مراجعه کند، معمولاً یک HTTP Response با Status Code خانواده 3xx و Header به نام Location ارسال می‌کند.

برای مثال ساختار مفهومی Response می‌تواند چنین باشد:

HTTP/1.1 302 Found
Location: https://example.com/account

Browser پس از دریافت Response به URL مشخص‌شده در Location مراجعه می‌کند.

MDN توضیح می‌دهد Header استاندارد Location برای تعیین مقصد Redirect استفاده می‌شود و در Responseهای Redirection خانواده 3xx معنای اصلی خود را پیدا می‌کند. RFC 9110 نیز رفتار Status Codeهای Redirect و نقش Location را تعریف کرده است.

Redirect به‌خودی‌خود هیچ اشکال امنیتی ندارد.

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

برای مثال:

بعد از Login،

بعد از Logout،

پس از ثبت فرم،

پس از پرداخت،

هنگام تغییر URL یک صفحه،

انتقال از HTTP به HTTPS،

انتقال از دامنه قدیمی به دامنه جدید،

بازگرداندن User به صفحه قبلی،

ورود با Google یا سایر OAuth Providerها،

لینک‌های Tracking،

و انتقال User به Partnerهای تجاری.

بنابراین مشکل «وجود Redirect» نیست.

مشکل زمانی ایجاد می‌شود که User بتواند مقصد Redirect را تعیین کند و Application بدون تصمیم امنیتی مستقل آن را بپذیرد.

Open Redirect چیست؟

MITRE آسیب‌پذیری Open Redirect را با شناسه CWE-601 و عنوان:

URL Redirection to Untrusted Site ('Open Redirect')

تعریف می‌کند.

در این Weakness، Application داده کنترل‌شده توسط User را می‌پذیرد که مقصد یک Link یا Redirect خارجی را مشخص می‌کند و سپس از همان مقدار برای هدایت User استفاده می‌کند.

OWASP نیز Unvalidated Redirect را حالتی می‌داند که Application مقصد Redirect را از یک Input غیرقابل‌اعتماد دریافت می‌کند و بدون Validation مناسب User را به آن مقصد هدایت می‌کند.

مدل امن می‌تواند چنین باشد:

User Request
     ↓
Application
     ↓
Server-defined destination
     ↓
Trusted Page

اما در طراحی آسیب‌پذیر:

User-controlled destination
          ↓
Application Redirect
          ↓
Arbitrary External Website

Application در عمل تبدیل به یک Redirector مورد اعتماد می‌شود که هر شخص می‌تواند برای انتقال کاربران به مقصد دیگری از آن استفاده کند.

یک مثال ساده از Open Redirect

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

URL ممکن است چنین باشد:

/login?next=/dashboard

پس از Login، Application مقدار next را دریافت کرده و Redirect می‌کند.

این طراحی در صورتی که فقط Pathهای داخلی معتبر را قبول کند، می‌تواند کاملاً مناسب باشد.

اما فرض کنیم Logic برنامه چیزی شبیه این باشد:

destination = request["next"]
redirect(destination)

Application هیچ بررسی دیگری انجام نمی‌دهد.

حالا Input به‌جای:

/dashboard

می‌تواند یک URL خارجی باشد.

مشکل اصلی همین است:

Application تصور کرده next یک مسیر داخلی خواهد بود، اما این فرض را در Server enforce نکرده است.

این نمونه خوبی از تفاوت میان:

Expected Input

و:

Enforced Input

است.

امنیت براساس چیزی که Developer انتظار دارد User ارسال کند ایجاد نمی‌شود؛ Server باید آن Rule را واقعاً enforce کند. Open Redirect چگونه ایجاد می‌شود؟

Open Redirect چگونه ایجاد می‌شود؟

معمولاً آسیب‌پذیری از ترکیب دو عامل ایجاد می‌شود:

اول اینکه Destination از User Input دریافت می‌شود.

دوم اینکه قبل از Redirect، Destination به اندازه کافی Validate نمی‌شود.

Sourceهای رایج Destination عبارت‌اند از:

?url=
?next=
?redirect=
?redirect_uri=
?return=
?return_url=
?continue=
?destination=
?callback=
?goto=

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

ممکن است Endpoint دارای next باشد ولی فقط مقدارهای امن و داخلی را قبول کند.

بنابراین هنگام بررسی امنیتی، صرف مشاهده Parameter کافی نیست؛ Data Flow باید تا Redirect Sink دنبال شود.

Redirect Sink چیست؟

Sink نقطه‌ای است که Application واقعاً Redirect را انجام می‌دهد.

در Technologyهای مختلف ممکن است با APIهای متفاوتی مواجه شویم.

در PHP معمولاً:

header( 'Location: ' . $location );

در Frameworkهای دیگر Functionهایی مانند:

redirect()
sendRedirect()
Response.Redirect()
redirect_to()

وجود دارند.

در Browser نیز JavaScript می‌تواند Redirect سمت Client انجام دهد.

برای مثال مفاهیمی مانند:

window.location
location.href
location.assign()

می‌توانند Browser را به URL دیگری منتقل کنند.

OWASP WSTG به‌طور جداگانه Client-Side URL Redirect را بررسی می‌کند و آن را زمانی آسیب‌پذیر می‌داند که داده User-Controlled مقصد Redirect مرورگر شود.

بنابراین Open Redirect فقط یک مشکل Backend نیست.

Server-Side Open Redirect چیست؟

در Server-Side Redirect، Backend یک HTTP Redirect Response ایجاد می‌کند.

مثلاً:

Request
  ↓
Server
  ↓
302 + Location
  ↓
Browser

اگر Location از داده غیرقابل‌اعتماد ساخته شود، Server-Side Open Redirect ایجاد می‌شود.

این نوع Redirect معمولاً در:

Login،

Logout،

Authentication Middleware،

Payment Flow،

Tracking Endpoint،

Short Link،

OAuth،

و Redirect Utilityها

مشاهده می‌شود.

Client-Side Open Redirect چیست؟

گاهی Server مستقیماً Status Code 3xx ارسال نمی‌کند.

در عوض JavaScript Browser مقصد را تعیین می‌کند.

برای مثال Application ممکن است Parameter URL را بخواند و سپس:

window.location = destination

را اجرا کند.

از دید User نتیجه تقریباً مشابه است:

Browser از Domain معتبر به مقصدی دیگر منتقل می‌شود.

OWASP WSTG برای Client-Side Redirect توصیه می‌کند نقاطی که URL یا Path قابل‌کنترل User وارد Functionهای تغییر Location می‌شوند شناسایی شوند و محدوده مقصد قابل هدایت بررسی گردد. چرا Open Redirect خطرناک است؟

چرا Open Redirect خطرناک است؟

ممکن است در نگاه اول Open Redirect نسبت به SQL Injection یا RCE کم‌خطر به نظر برسد.

Application مستقیماً Code مهاجم را اجرا نمی‌کند.

Database نیز الزاماً افشا نمی‌شود.

اما ارزش این Vulnerability به Context بستگی دارد.

Open Redirect می‌تواند:

اعتماد User به Domain اصلی را سوءاستفاده کند،

Phishing را معتبرتر جلوه دهد،

در زنجیره OAuth یا Authentication قرار گیرد،

بعضی Domain Validationها را دور بزند،

به انتقال Sensitive URL Parameter کمک کند،

و در بعضی Architectureها به ضعف‌های دیگر متصل شود.

OWASP تأکید می‌کند ارزش اصلی Open Redirect در بسیاری از حملات مدرن، نقش آن به‌عنوان Building Block در Exploit Chain است. Open Redirect و Phishing

Open Redirect و Phishing

Phishing شناخته‌شده‌ترین کاربرد Open Redirect است.

در Phishing معمولی، User ممکن است قبل از کلیک روی Link، Domain مقصد را بررسی کند.

اگر Link مستقیماً به Domain ناشناس اشاره کند، احتمال شک کردن User بیشتر است.

اما Open Redirect به Attacker اجازه می‌دهد Link با Domain معتبر آغاز شود.

ساختار مفهومی:

https://trusted.example/redirect?destination=...

User در ابتدای URL دامنه مورد اعتماد را مشاهده می‌کند.

پس از باز کردن Link، Application واقعی Redirect را انجام می‌دهد و Browser وارد مقصد خارجی می‌شود.

OWASP و MITRE هر دو این موضوع را از پیامدهای اصلی CWE-601 می‌دانند: چون Link ابتدا روی Domain معتبر قرار دارد، Phishing می‌تواند ظاهر قابل‌اعتمادتری پیدا کند.

البته Open Redirect به‌تنهایی User را مجبور به وارد کردن Password نمی‌کند.

Impact نهایی به رفتار User و محتوای Destination وابسته است.

چرا URL معتبر اولیه باعث افزایش اعتماد می‌شود؟

کاربر معمولاً هنگام مشاهده Link بیشتر به بخش ابتدایی آن توجه می‌کند.

اگر Link از Domain بانک، فروشگاه یا Application شناخته‌شده شروع شود، احتمال کلیک افزایش پیدا می‌کند.

این موضوع به‌خصوص در:

Email،

SMS،

Notification،

QR Code،

و لینک‌های کوتاه‌شده

اهمیت دارد.

بنابراین یکی از دلایل اصلی جلوگیری از Open Redirect، جلوگیری از تبدیل Brand Domain به ابزار هدایت قابل سوءاستفاده است. Open Redirect و OAuth

Open Redirect و OAuth

یکی از مهم‌ترین Contextهایی که Open Redirect می‌تواند خطرناک‌تر شود، OAuth 2.0 است.

Authorization Server معمولاً Client را فقط به Redirect URIهای ثبت‌شده هدایت می‌کند.

هدف این است که Authorization Code یا سایر داده‌های Authorization فقط به Application مجاز برگردند.

اما فرض کنید Redirect URI ثبت‌شده به صفحه‌ای روی Domain Client برسد که خودش Open Redirect دارد.

در این حالت ممکن است یک Destination معتبر در مرحله اول، User را در مرحله بعد به Domain دیگری منتقل کند.

به همین دلیل Security Guidance جدید OAuth روی Exact Redirect URI Validation و حذف Redirectهای ناامن تأکید زیادی دارد.

OWASP نیز Open Redirect را یکی از Weaknessهایی معرفی می‌کند که ممکن است در OAuth Attack Chain برای عبور از Domain-based Validation مورد استفاده قرار گیرد.

بنابراین Open Redirect روی یک صفحه عادی Marketing و Open Redirect داخل OAuth Callback Context الزاماً Severity یکسانی ندارند.

Open Redirect به‌عنوان بخشی از Exploit Chain

یکی از اشتباهات رایج این است که Open Redirect فقط براساس رفتار مستقل خودش ارزیابی شود.

مثلاً گفته شود:

«فقط User را Redirect می‌کند، پس اهمیتی ندارد.»

در ارزیابی حرفه‌ای باید پرسید:

این Endpoint در چه Workflowهایی Trusted است؟

آیا OAuth Provider آن Domain را Trusted می‌داند؟

آیا API دیگری Destinationهای این Domain را اجازه می‌دهد؟

آیا Emailهای رسمی به آن Link می‌دهند؟

آیا URL دارای Token است؟

آیا Redirect باعث انتقال Query String حساس می‌شود؟

آیا یک Server-Side HTTP Client Redirectهای این Domain را Follow می‌کند؟

ترکیب ضعف‌ها می‌تواند Impact را چند برابر کند.

ارتباط Open Redirect و SSRF

Open Redirect و SSRF دو Vulnerability متفاوت هستند.

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

در Open Redirect، Browser یا Client از URL فعلی به URL دیگری هدایت می‌شود.

اما در بعضی Architectureها Open Redirect می‌تواند بخشی از یک SSRF Chain باشد.

فرض کنید یک Server-Side HTTP Client فقط Request به Domain مورداعتماد را قبول کند اما Automatically Redirectها را Follow کند.

اگر همان Domain دارای Open Redirect باشد، Validation اولیه ممکن است فقط Host اول را ببیند و Client بعداً به Destination دیگری منتقل شود.

این موضوع نشان می‌دهد Validation URL باید Destination نهایی و Redirect Policy را نیز در Threat Model در نظر بگیرد.

با این حال:

Open Redirect ≠ SSRF

و هر Finding باید Root Cause صحیح خودش را داشته باشد.

تفاوت Open Redirect با Host Header Injection

این دو ضعف ممکن است هر دو باعث Redirect به Domain خارجی شوند، اما Source مشکل متفاوت است.

در Open Redirect، معمولاً یک Parameter مانند:

next
return
url
redirect

Destination را کنترل می‌کند.

در Host Header Injection، Application ممکن است Domain را از HTTP Host یا Forwarded Header استخراج کند.

بنابراین:

Open Redirect
→ Untrusted Redirect Destination

در مقابل:

Host Header Injection
→ Untrusted Authority / Host

است.

گاهی هر دو ضعف می‌توانند در یک URL Builder وجود داشته باشند.

تفاوت Open Redirect با XSS

Open Redirect Script مهاجم را روی Origin سایت اجرا نمی‌کند.

Browser فقط به Domain دیگری منتقل می‌شود.

در XSS، Code مهاجم معمولاً در Security Context همان Origin اجرا می‌شود.

بنابراین Impact فنی این دو متفاوت است.

Open Redirect ممکن است برای هدایت User به صفحه Phishing استفاده شود، اما Same-Origin Privilege سایت اصلی را مانند XSS به Attacker نمی‌دهد.

تفاوت Open Redirect با Forward

Redirect و Forward نیز دقیقاً یکسان نیستند.

Redirect معمولاً Browser را به URL دیگری می‌فرستد.

در Server-Side Forward، Framework ممکن است Request را داخل Server به Handler یا Resource دیگری منتقل کند، بدون اینکه Browser الزاماً Destination جدید را ببیند.

OWASP Cheat Sheet هر دو مفهوم Unvalidated Redirects and Forwards را بررسی می‌کند و اشاره می‌کند Forward ناامن ممکن است در بعضی طراحی‌ها باعث دور زدن Access Control شود.

بنابراین هنگام Audit باید مشخص شود:

عملیات Browser Redirect است؟

Internal Rewrite است؟

یا Server-Side Forward؟

HTTP Redirect چگونه انجام می‌شود؟

Redirectهای HTTP با Status Codeهای مختلف انجام می‌شوند.

رایج‌ترین آنها عبارت‌اند از:

Statusمعنی کلی
301انتقال دائمی
302انتقال موقت
303مشاهده Resource دیگر
307انتقال موقت با حفظ Method
308انتقال دائمی با حفظ Method

RFC 9110 و MDN رفتار این Status Codeها را توضیح داده‌اند. برای مثال 307 و 308 Method درخواست را حفظ می‌کنند، در حالی که 303 Client را برای Resource مقصد به GET هدایت می‌کند.

از دید Open Redirect، مهم‌ترین موضوع معمولاً خود Destination است.

اما انتخاب Status اشتباه نیز می‌تواند Side Effect ایجاد کند.

چرا 307 و 308 حساس‌تر از بعضی Redirectها هستند؟

چون این Statusها Method درخواست را حفظ می‌کنند.

اگر Request اصلی POST بوده، Redirect ممکن است POST را نیز به مقصد جدید بفرستد.

این مسئله به‌تنهایی اثبات افشای اطلاعات نیست؛ رفتار Browser، Request Body و Architecture اهمیت دارند.

اما هنگام طراحی Redirectهایی که Destination آنها حتی احتمالاً خارجی است، باید اثر Method Preservation نیز در Threat Model بررسی شود.

Redirect امن فقط «Domain امن» نیست.

نوع Redirect نیز باید با Workflow هماهنگ باشد.

Open Redirect در Login

یکی از رایج‌ترین محل‌ها، Login Flow است.

Application می‌خواهد User پس از Login به صفحه قبلی برگردد.

مثلاً:

Protected Page
     ↓
Login
     ↓
Return to original page

این قابلیت UX خوبی ایجاد می‌کند.

اما Destination باید به Session یا Path داخلی معتبر محدود باشد.

مدل مناسب:

/login?next=/account/orders

و Backend بررسی کند که:

Destination Relative Path است،

Host خارجی ندارد،

Scheme ندارد،

و در صورت نیاز Path نیز داخل محدوده مجاز قرار دارد.

مدل ضعیف این است که هر URL واردشده بعد از Authentication اجرا شود.

چنین طراحی‌ای باعث می‌شود Open Redirect دقیقاً در نقطه‌ای ایجاد شود که User انتظار اعتماد بالایی دارد.

Open Redirect در Logout

Logout نیز اغلب Parameter مقصد دارد.

برای مثال Application بعد از خروج User را به Home Page، Landing Page یا Identity Provider هدایت می‌کند.

اگر Destination آزاد باشد، یک Link ممکن است ابتدا User را Logout کرده و سپس فوراً به Domain دیگری منتقل کند.

این نوع Flow می‌تواند برای Social Engineering مناسب باشد.

بنابراین return_to در Logout نیز باید همان قواعد امنیتی سایر Redirectها را داشته باشد.

Open Redirect در Payment Flow

بعد از پرداخت، Gateway یا Application ممکن است User را به صفحه موفقیت یا شکست برگرداند.

Destination نباید از Parameter کاملاً آزاد Client ساخته شود.

در Payment Context علاوه بر Redirect باید موارد دیگری مانند:

Payment Status،

Transaction ID،

Order Ownership،

Amount،

Server-to-Server Verification

نیز مستقل بررسی شوند.

رسیدن Browser به یک Success URL به‌تنهایی اثبات پرداخت نیست.

Open Redirect در این Context نباید Business Logic پرداخت را تحت تأثیر قرار دهد.

Open Redirect در لینک‌های Tracking

Marketing Systemها اغلب Endpointهایی دارند که ابتدا Click را ثبت و سپس User را Redirect می‌کنند.

مثلاً:

/tracking?id=...

بهتر است id به Destination ذخیره‌شده Server-Side Map شود.

یعنی:

campaign_1001
   ↓
Database
   ↓
Known Destination

به‌جای اینکه URL کامل Destination در Query Parameter قرار گیرد.

OWASP نیز توصیه می‌کند در صورت امکان User یک Short Name، ID یا Token ارائه دهد و Server آن را به URL کامل Map کند. این رویکرد Attack Surface دستکاری مستقیم Destination را کاهش می‌دهد.

Short URL Service به‌صورت طبیعی User را Redirect می‌کند.

بنابراین در چنین سیستمی Redirect خارجی خود Feature است.

اینجا «Redirect خارجی» را نمی‌توان به‌طور کامل مسدود کرد.

Security Model باید متفاوت باشد.

برای مثال:

Abuse Monitoring،

Domain Reputation،

Malware/Phishing Detection،

Rate Limit،

Reporting،

Preview Page،

Expiration،

و Governance

می‌توانند لازم باشند.

این مثال نشان می‌دهد Security Rule همیشه Context-Based است.

برای Application معمولی Allowlist خارجی مناسب است، اما برای URL Shortener ممکن است Business Purpose دقیقاً هدایت خارجی باشد.

URL Validation چرا سخت‌تر از چیزی است که به نظر می‌رسد؟

Developer ممکن است تصور کند کافی است String مقصد شامل نام Domain سایت باشد.

مثلاً:

if "example.com" in url:
    allow

این روش مناسب نیست.

چون وجود یک String در URL به معنی Host بودن آن نیست.

URL اجزای مختلف دارد:

Scheme،

Username،

Password،

Host،

Port،

Path،

Query،

Fragment.

Validation امنیتی باید URL را با Parser استاندارد Parse کند و Component مناسب را مقایسه کند.

String Search یا Regex بسیار عمومی اغلب Representation واقعی URL را به‌درستی مدل نمی‌کند.

اشتباه startsWith در Validation

فرض کنید Rule چنین باشد:

URL باید با https://example.com شروع شود.

در نگاه اول منطقی است.

اما Prefix Matching به‌تنهایی نمی‌گوید Boundary واقعی Host کجاست.

برای Security Check بهتر است URL Parse شود و سپس:

scheme == https
host == example.com
port == expected

بررسی شود.

Validation باید Semantic باشد، نه صرفاً String-Based.

اشتباه endsWith

در سیستم‌های Subdomain گاهی از Ruleهایی مثل:

host endsWith "example.com"

استفاده می‌شود.

این نیز اگر Boundary Domain به‌درستی بررسی نشود می‌تواند Domainهای مشابه را اشتباه معتبر کند.

بهتر است Rule روشن باشد:

host == example.com
OR
host is a valid subdomain of .example.com

و Parser استاندارد برای استخراج Host استفاده شود.

خطر URLهای Scheme-Relative

URLهایی که با:

//

شروع می‌شوند ممکن است توسط Browser به‌عنوان URL وابسته به Scheme فعلی تفسیر شوند.

یعنی:

//destination.example

می‌تواند External Host باشد، حتی اگر http:// یا https:// صریحاً در ابتدای String وجود نداشته باشد.

مستندات WordPress در wp_validate_redirect() نیز این حالت را به‌طور خاص در Validation لحاظ می‌کنند و مقدار شروع‌شونده با // را برای بررسی صحیح به شکل URL تفسیر می‌کنند.

این مثال نشان می‌دهد چرا نوشتن URL Validator اختصاصی بدون درک کامل Parser Behavior پرریسک است.

Encoding و Canonicalization

URL ممکن است Characterهایی به‌صورت Percent-Encoding داشته باشد.

همچنین:

Case،

Port پیش‌فرض،

Dot Segmentها،

Unicode Domain،

Trailing Dot،

و Encodingهای مختلف

می‌توانند Representation را پیچیده کنند.

امنیت باید بر Canonical Representation مناسب بنا شود.

اصل مناسب:

Parse
↓
Normalize where appropriate
↓
Validate semantic components
↓
Use

نه:

Raw string
↓
چند replace
↓
اعتماد

Denylist کافی نیست

گاهی Developer لیستی مانند زیر ایجاد می‌کند:

block attacker.com
block phishing.com
block bad.example

این مدل مقیاس‌پذیر نیست.

Domainهای جدید بی‌نهایت‌اند.

MITRE و OWASP در Prevention به Accept Known Good یا Allowlist تأکید دارند.

برای Applicationی که فقط Redirectهای محدود دارد، باید بگوییم:

فقط این مقصدها مجازند.

نه:

همه مقصدها مجازند مگر چند مورد بد.

بهترین روش: URL را از User نگیرید

OWASP ساده‌ترین و قدرتمندترین Mitigation را این می‌داند:

اگر امکان دارد، URL کامل Destination را از User Input نپذیرید.

مثلاً به‌جای:

?redirect=https://...

از:

?destination=dashboard

استفاده کنید.

Server Map دارد:

dashboard → /account/dashboard
orders    → /account/orders
profile   → /account/profile

در نتیجه User نمی‌تواند یک Domain Arbitrary معرفی کند.

استفاده از Relative Path

اگر Redirect فقط داخل همان Application انجام می‌شود، Relative Path اغلب Attack Surface کمتری دارد.

مثلاً:

/account
/orders
/dashboard

به‌جای Absolute URL.

البته صرف شروع با / نیز نباید تنها Security Check باشد.

Path باید Parse و Normalize شود و Application باید مطمئن شود Formatهای خاص به External Authority تبدیل نمی‌شوند.

اما از نظر Design، محدود کردن Feature به Path داخلی بسیار امن‌تر از پذیرش URL کامل است.

Allowlist برای Redirect خارجی

گاهی Redirect به سایت دیگری واقعاً Business Requirement است.

مثلاً:

Partner Portal،

Payment Provider،

Corporate SSO،

Support System.

در این شرایط Allowlist مناسب است.

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

Scheme،

Host،

Port،

و در صورت نیاز Path Prefix مشخص.

مثلاً Policy می‌تواند بگوید:

Scheme: HTTPS only

Allowed hosts:
accounts.example-partner.com
payment.example-provider.com

بهتر است Allowlist کوتاه، مستند و تحت Configuration Management باشد.

تأیید کاربر قبل از خروج از سایت

OWASP یک Mitigation دیگر نیز پیشنهاد می‌کند: اگر Redirect به Domain خارجی ضروری است، ابتدا صفحه‌ای نمایش داده شود که Destination را به‌طور واضح به User نشان دهد و User خودش ادامه مسیر را تأیید کند.

برای مثال:

شما در حال خروج از example.com هستید.

مقصد:
partner.example

ادامه
لغو

این روش جای Validation نیست.

اما برای لینک‌های خارجی مجاز می‌تواند Transparency را افزایش دهد.

آیا Nonce از Open Redirect جلوگیری می‌کند؟

MITRE استفاده از Nonce غیرقابل‌پیش‌بینی را یکی از Mitigationهای معماری برای بعضی Redirect Requestها ذکر می‌کند.

اما Nonce Root Fix آزاد بودن Destination نیست.

اگر User معتبر بتواند Redirect Arbitrary تولید کند، وجود Nonce ممکن است تنها قابلیت ساخت Link توسط Actor خارجی را محدود کند.

بهترین طراحی همچنان Validation مقصد و حذف URL Arbitrary است.

Nonce می‌تواند لایه دفاع اضافه باشد، نه جایگزین Destination Validation. Open Redirect در WordPress

Open Redirect در WordPress

در WordPress، Pluginها و Themeهای سفارشی ممکن است Redirectهای مختلفی ایجاد کنند.

نمونه‌ها:

بعد از Login،

پس از Submit فرم،

بعد از تنظیمات Admin،

Checkout،

Membership،

OAuth Integration،

و Landing Page.

WordPress دو Function مهم برای این موضوع دارد:

wp_redirect()
wp_safe_redirect()

این دو یکسان نیستند.

wp_redirect و خطر Open Redirect

wp_redirect() برای Redirect عمومی استفاده می‌شود.

مستندات WordPress توضیح می‌دهند این Function Redirect را انجام می‌دهد و خودش اجرای PHP را متوقف نمی‌کند؛ معمولاً باید بعد از آن exit استفاده شود.

نکته امنیتی مهم این است که wp_redirect() به‌تنهایی بررسی نمی‌کند URL متعلق به Host محلی سایت است.

بنابراین ساختاری مانند:

User Input
   ↓
wp_redirect()

بدون Validation می‌تواند خطرناک باشد.

اگر Redirect خارجی واقعاً لازم نیست، wp_safe_redirect() انتخاب مناسب‌تری است.

wp_safe_redirect چیست؟

مستندات رسمی WordPress می‌گویند wp_safe_redirect() یک Redirect امن محلی انجام می‌دهد و Host مقصد را از طریق Validation بررسی می‌کند. اگر Host مجاز نباشد، از Destination جایگزین استفاده می‌شود.

مدل:

wp_safe_redirect( $url );
exit;

برای URLهایی که از User Input یا Context غیرکاملاً‌قابل‌اعتماد می‌آیند مناسب‌تر است، مشروط بر اینکه هدف Redirect داخلی باشد.

wp_safe_redirect() از wp_validate_redirect() استفاده می‌کند.

wp_validate_redirect چگونه کار می‌کند؟

wp_validate_redirect() یک URL را برای استفاده در Redirect بررسی می‌کند.

اگر URL Absolute باشد، Host آن با Hostهای مجاز مقایسه می‌شود.

در صورت نامعتبر بودن، یک Fallback URL برگردانده می‌شود.

WordPress همچنین Filter زیر را دارد:

allowed_redirect_hosts

که Plugin می‌تواند Hostهای اضافی مجاز را تعریف کند.

این Feature باید با دقت استفاده شود.

اضافه کردن دامنه‌های بسیار گسترده یا مقادیر User-Controlled به Allowlist، هدف Validation را از بین می‌برد.

wp_safe_redirect هم exit نمی‌کند

نکته مهم برای Developerهای WordPress این است که:

wp_safe_redirect()

اجرای Script را به‌صورت خودکار متوقف نمی‌کند.

Documentation رسمی توصیه می‌کند تقریباً همیشه بعد از آن:

exit;

استفاده شود.

این موضوع مستقیماً Open Redirect نیست، اما برای کنترل Flow برنامه مهم است.

نمونه طراحی ناامن در Plugin وردپرس

مدل مفهومی ناامن:

$_GET['return_to']
       ↓
wp_redirect()
       ↓
Redirect

اگر return_to بتواند URL خارجی داشته باشد و هیچ Validation دیگری وجود نداشته باشد، Plugin ممکن است Open Redirect ایجاد کند.

مدل بهتر برای Redirect داخلی:

Input
 ↓
wp_safe_redirect()
 ↓
Validated local destination
 ↓
exit

و اگر Destinationها محدود هستند حتی بهتر است User فقط یک ID ارسال کند و Server Path نهایی را انتخاب کند.

چگونه Open Redirect را شناسایی کنیم؟

تست باید فقط روی Application متعلق به خودتان یا سامانه‌ای که مجوز بررسی آن را دارید انجام شود.

برای شناسایی Open Redirect نیازی به Phishing واقعی یا Domain مخرب نیست.

یک Domain آزمایشی و کنترل‌شده کافی است.

اول Endpointهایی را پیدا کنید که Redirect دارند.

برای مثال:

Login،

Logout،

Search،

Tracking،

OAuth Callback،

Payment Return،

Short Links.

سپس Inputهایی که Destination را کنترل می‌کنند مشخص کنید.

تست امن Redirect

هدف این است که ببینیم Destination خارج از محدوده مجاز پذیرفته می‌شود یا خیر.

در Environment آزمایشی می‌توان از یک Domain رزروشده یا Domain Test متعلق به تیم استفاده کرد.

سپس Response بررسی شود:

Status Code چیست؟

Location چیست؟

آیا Browser وارد Domain آزمایشی می‌شود؟

آیا Redirect سمت Client انجام می‌شود؟

آیا Validation قبل از Redirect انجام شده؟

نیازی نیست Page مقصد Credential جمع‌آوری کند یا رفتار مخربی داشته باشد.

Code Review برای Open Redirect

در Code Review دو چیز را پیدا کنید:

Source و Sink.

Source:

query parameter
form input
cookie
request header
database value influenced by user
API input

Sink:

redirect()
Location header
window.location
location.href
wp_redirect()

سپس Data Flow:

Untrusted Input
      ↓
Validation?
      ↓
Redirect Sink

بررسی می‌شود.

وجود Redirect Function به‌تنهایی Vulnerability نیست.

باید مشخص شود Destination چطور ایجاد شده است.

SAST و Open Redirect

Static Application Security Testing معمولاً می‌تواند Patternهایی مانند:

request parameter
      ↓
redirect API

را پیدا کند.

Open Redirect از Vulnerabilityهایی است که Data Flow Analysis برای آن مفید است.

اما False Positive امکان دارد.

ممکن است بین Source و Sink Allowlist مناسبی وجود داشته باشد.

بنابراین Finding خودکار باید دستی تأیید شود.

DAST

DAST می‌تواند Endpointهای Redirect را پیدا کرده و Parameterهای مربوط را تغییر دهد.

اما Scanner باید رفتار Redirect Chain را به‌دقت تحلیل کند.

همچنین Testing روی Production باید Side Effect نداشته باشد.

OAuth و Payment Flow به‌خصوص بهتر است روی Staging یا Account Test بررسی شوند.

Client-Side Code Review

برای Open Redirect سمت Client باید Sourceهای زیر نیز بررسی شوند:

location.search
location.hash
document.URL
postMessage data
storage values

و Sinkهایی مانند:

location.href
location.assign
window.open

هدف بررسی این است که آیا URL غیرقابل‌اعتماد بدون Validation به Navigation API داده می‌شود.

OWASP WSTG همین نوع Data Flow را در تست Client-Side URL Redirect بررسی می‌کند.

آیا JavaScript URL Validation کافی است؟

اگر Redirect نهایی توسط Backend انجام می‌شود، Validation فقط در JavaScript کافی نیست.

User می‌تواند Request را بدون UI ارسال کند.

حتی برای Client-Side Redirect نیز بهتر است Destination List یا Mapping مشخص داشته باشیم.

Security Controlهای حساس نباید فقط به Disable Button یا Validation UI وابسته باشند.

Open Redirect و Access Control

گاهی Server-Side Forward یا Redirect Logic در کنترل Flow داخلی نقش دارد.

فرض کنید Application بررسی کند:

if authorized:
    forward to protected page
else:
    forward elsewhere

اگر User بتواند Target Forward را مستقیماً کنترل کند، ممکن است Handler غیرمجاز فراخوانی شود.

OWASP اشاره می‌کند Unvalidated Forwardها می‌توانند در بعضی معماری‌ها باعث دور زدن Access Control شوند.

Authorization باید روی Resource مقصد نیز enforce شود.

نباید به این فرض تکیه کنیم که User فقط از مسیر Navigation موردنظر به Endpoint می‌رسد.

تفاوت Redirect با Authorization

یکی از اشتباهات طراحی:

User نمی‌تواند Link صفحه Admin را ببیند
پس نمی‌تواند وارد Admin شود.

Redirect و Navigation Access Control نیستند.

حتی اگر Menu یا Redirect User را هرگز به Endpoint Admin نبرد، Endpoint Admin خودش باید Authorization داشته باشد.

Open Redirect نباید بتواند Security Boundary را تعیین کند.

Logging Redirectهای مشکوک

Application می‌تواند Eventهایی مثل موارد زیر را Monitor کند:

Unknown Redirect Host،

Rejected Destination،

Redirect به External Domain،

Redirect Validation Failure،

OAuth Callback Destination Failure.

افزایش ناگهانی چنین Eventهایی ممکن است نشانه Scanning یا Abuse باشد.

با این حال Log نباید Tokenهای Sensitive موجود در URL را کامل ذخیره کند.

در Logging باید Redaction رعایت شود.

Redirectها و اطلاعات حساس در URL

اگر URL شامل:

Access Token،

Password Reset Token،

Magic Link Token،

Personal Data

باشد، Redirect خارجی می‌تواند خطر Leakage را افزایش دهد.

بهترین راه این است که Secretهای غیرضروری در URL نباشند.

همچنین Callback Pageهای حساس بهتر است Third-Party Resourceهای غیرضروری نداشته باشند.

Open Redirect در چنین Contextی Severity بیشتری دارد.

Referrer و Redirect

هنگام Navigation بین صفحات ممکن است Browser براساس Referrer Policy اطلاعاتی درباره صفحه قبلی برای Destination ارسال کند.

به همین دلیل Application نباید Security Design خود را صرفاً بر این فرض بنا کند که Query String هیچ‌گاه به مقصد دیگر نشت نمی‌کند.

Referrer-Policy می‌تواند Defense in Depth باشد.

اما Root Solution مدیریت صحیح Sensitive Data و Redirect Validation است.

Redirect و Cache

بعضی Redirect Responseها قابل Cache شدن هستند.

به‌خصوص Redirectهای دائمی مانند 301 و 308 می‌توانند رفتار طولانی‌مدت ایجاد کنند.

RFC 9110 درباره Cacheability برخی Status Codeهای Redirect توضیح می‌دهد.

بنابراین Redirect Dynamic و Security-Sensitive نباید بی‌دلیل Permanent باشد.

اگر Redirect Configuration اشتباه Cache شود، حتی بعد از Fix نیز بعضی Clientها ممکن است رفتار قدیمی را حفظ کنند.

301 یا 302؛ کدام برای Redirect پویا مناسب‌تر است؟

پاسخ به Use Case بستگی دارد.

301 برای جابه‌جایی دائمی Resource طراحی شده است.

302 برای مقصد موقت استفاده می‌شود.

Redirectهای Authentication و Post-Login معمولاً نباید به‌صورت Permanent در Browser Cache تثبیت شوند.

این موضوع مستقیماً Open Redirect را رفع نمی‌کند، اما انتخاب Status صحیح بخشی از Secure HTTP Design است. راهکار اصلی جلوگیری از Open Redirect

راهکار اصلی جلوگیری از Open Redirect

اولین اصل:

اگر URL کامل User-Controlled لازم نیست، آن را دریافت نکنید.

دوم:

اگر Destination فقط داخلی است، از Path یا ID داخلی استفاده کنید.

سوم:

اگر External Redirect لازم است، Destination را Parse و با Allowlist دقیق مقایسه کنید.

چهارم:

Redirect Security-Sensitive را به Session Context Bind کنید.

پنجم:

تمام Redirect Sinkها را در Code Review و تست‌های Regression پوشش دهید.

الگوی امن با Mapping

یکی از بهترین Designها:

destination=profile

Server:

profile → /account/profile
billing → /account/billing
orders  → /account/orders

اگر مقدار دیگری ارسال شود:

Reject
یا
Redirect to safe default

در این روش URL نهایی هیچ‌گاه مستقیماً توسط Client تعیین نمی‌شود.

الگوی امن برای External Redirect

اگر چند Partner مشخص وجود دارند:

partner=payment
partner=support
partner=docs

Server Map:

payment → https://payment.partner.example/
support → https://support.partner.example/
docs    → https://docs.partner.example/

User فقط Key را کنترل می‌کند.

این روش از Allowlist String نیز ساده‌تر و قابل Auditتر است.

در صورت پذیرش URL کامل چه کنیم؟

گاهی Architecture چاره دیگری ندارد.

در این شرایط:

URL را با Parser استاندارد Parse کنید.

Scheme را Explicitly Allow کنید.

Host را Exact یا با Rule معتبر Subdomain مقایسه کنید.

Port را محدود کنید.

Username/Password URL Component را در صورت عدم نیاز Reject کنید.

Protocolهای غیر HTTP/HTTPS را قبول نکنید مگر Business Requirement روشن.

Domain را Normalize کنید.

در صورت Redirect چندمرحله‌ای Policy را دوباره روی Destinationهای بعدی اعمال کنید.

Validation را Server-Side انجام دهید.

چرا Regex تنها راهکار خوبی نیست؟

URL Grammar پیچیده است.

یک Regex ساده ممکن است:

Representationهای معتبر را Reject کند،

Representationهای خطرناک را قبول کند،

یا رفتار Parser واقعی Browser و Framework را متفاوت تفسیر کند.

بهتر است از URL Parser استاندارد Platform استفاده شود و سپس Componentها بررسی شوند.

Regex در صورت نیاز می‌تواند روی Component Parseشده استفاده شود، نه Raw URL کامل.

Secure Defaults

اگر Validation شکست خورد، Application باید رفتار Fail Closed داشته باشد.

مثلاً:

Invalid destination
       ↓
/home

یا:

Invalid destination
       ↓
400 Bad Request

نه اینکه بگوید:

Validation failed
but redirect anyway

Fallback باید ثابت و قابل‌اعتماد باشد.

Error Message

برای User لازم نیست جزئیات Validator نمایش داده شود.

پیام ساده:

مقصد انتقال معتبر نیست.

کافی است.

جزئیات Technical Validation می‌تواند در Log داخلی ثبت شود.

چک‌لیست دفاعی جلوگیری از Open Redirect

کنترلسؤال امنیتی
User-controlled URLآیا واقعاً لازم است User URL کامل تعیین کند؟
Server Mappingآیا می‌توان به‌جای URL از ID یا Name استفاده کرد؟
Relative Pathآیا Redirect داخلی را می‌توان فقط به Path محدود کرد؟
Allowlistآیا Hostهای خارجی مجاز دقیقاً مشخص شده‌اند؟
Schemeآیا فقط HTTPS یا Protocolهای ضروری پذیرفته می‌شوند؟
Host Parsingآیا Host با URL Parser استاندارد استخراج می‌شود؟
String Matchingآیا از Contains/StartsWith ناامن پرهیز شده است؟
Subdomainآیا Boundary دامنه به‌درستی بررسی می‌شود؟
Scheme-Relative URLآیا URLهای شروع‌شونده با // بررسی می‌شوند؟
Encodingآیا Validation بعد از Parsing/Normalization صحیح انجام می‌شود؟
Portآیا Portهای غیرمنتظره محدود شده‌اند؟
OAuthآیا Callback و Redirect URIها دقیق هستند؟
Loginآیا next فقط Destination امن را قبول می‌کند؟
Logoutآیا return_to محدود شده است؟
Trackingآیا ID به Destination Server-Side Map می‌شود؟
WordPressآیا برای Redirect داخلی از wp_safe_redirect() استفاده می‌شود؟
External WordPress Redirectآیا Host قبل از wp_redirect() صریحاً Trusted است؟
Client-Sideآیا window.location از Input خام تغذیه نمی‌شود؟
Loggingآیا Destinationهای Rejectشده Monitor می‌شوند؟
Sensitive URLآیا Token و Secret در Redirect URL قرار ندارند؟
Regression Testآیا تمام Redirect Endpointها بعد از تغییرات تست می‌شوند؟

اشتباهات رایج توسعه‌دهندگان

Domain ابتدایی فقط Endpoint Redirector است.

Destination واقعی باید بررسی شود.

بررسی https

HTTPS بودن Destination به معنی Trusted بودن Domain نیست.

یک Domain مخرب نیز می‌تواند Certificate معتبر HTTPS داشته باشد.

استفاده از Denylist

Block کردن چند Domain شناخته‌شده مانع استفاده از Domainهای دیگر نمی‌شود.

استفاده از contains

وجود example.com در String URL اثبات نمی‌کند Host همان example.com است.

اعتماد به Frontend

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

Allowlist بیش از حد گسترده

Allow کردن تمام Subdomainها بدون اینکه تمام آنها Trust Level یکسانی داشته باشند خطرناک است.

ممکن است یک Subdomain تحت کنترل User یا Third Party باشد.

Cookie نیز Client-Controlled است.

ذخیره Destination در Cookie به‌خودی‌خود آن را Trusted نمی‌کند.

Redirect به Referer بدون بررسی

HTTP Referer نیز نباید Source اعتماد مطلق برای Security-Sensitive Redirect باشد.

Hardcode نکردن Destination ثابت

گاهی Developer URL را از Request دریافت می‌کند در حالی که مقصد همیشه یکی است.

اگر مقصد ثابت است، آن را در Code یا Config قابل اعتماد تعریف کنید.

Open Redirect و CWE-601

شناسه اصلی این Weakness در MITRE:

CWE-601

است.

برخلاف بعضی CWEهای بسیار کلی، CWE-601 یک Base Weakness است و برای Mapping Vulnerabilityهای واقعی Open Redirect قابل استفاده است. MITRE پیامدهایی مانند Phishing، انتقال User به Untrusted Site و کمک به Bypass بعضی Protection Mechanismها را برای آن توضیح می‌دهد.

Open Redirect در OWASP Top 10:2025

OWASP Top 10:2025، CWE-601 را در A01:2025 Broken Access Control قرار داده است.

این موضوع به معنی آن نیست که هر Open Redirect یک Access Control Bypass مستقیم ایجاد می‌کند.

OWASP Top 10 گروه‌بندی Risk Categoryهاست و CWEهای مختلف را زیر Root Causeهای گسترده‌تر دسته‌بندی می‌کند.

Severity هر Open Redirect همچنان باید جداگانه براساس Context ارزیابی شود.

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

Open Redirect Severity ثابت ندارد.

موارد مهم عبارت‌اند از:

Redirect قبل یا بعد از Authentication است؟

Destination خارجی آزاد است؟

Domain رسمی و حساس است؟

Endpoint در Emailهای رسمی استفاده می‌شود؟

OAuth یا SSO از Endpoint استفاده می‌کند؟

Sensitive Token در URL وجود دارد؟

Redirect Chain در سیستم دیگری Trusted است؟

User Interaction لازم است؟

Application کاربرانی با سطح حساس دارد؟

برای مثال:

Open Redirect روی یک Demo Page با User Interaction زیاد

با:

Open Redirect روی OAuth Callback دارای Authorization Code

یکسان نیست.

آیا Open Redirect همیشه آسیب‌پذیری High است؟

خیر.

در بعضی Contextها ممکن است Severity پایین باشد.

در بعضی Bug Bountyها Open Redirect ساده حتی Informational محسوب می‌شود، مگر اینکه Impact اضافی مانند OAuth Token Leakage یا Bypass دیگری اثبات شود.

گزارش امنیتی حرفه‌ای نباید Severity را فقط از عنوان Vulnerability استخراج کند.

Impact واقعی باید اثبات شود.

گزارش حرفه‌ای Open Redirect

یک Report مناسب باید شامل موارد زیر باشد:

Affected Endpoint،

Source Parameter،

Expected Behavior،

Observed Behavior،

Redirect Destination Scope،

Authentication Requirement،

Business/Security Context،

و Remediation.

مثلاً:

Expected:
Parameter return_to فقط باید مسیرهای داخلی را بپذیرد.

Observed:
یک URL خارجی آزمایشی به‌عنوان مقصد پذیرفته می‌شود
و Application پاسخ Redirect تولید می‌کند.

Impact:
دامنه مورد اعتماد می‌تواند برای انتقال کاربران به
سایت‌های خارجی استفاده شود.

Remediation:
استفاده از Server-side destination mapping یا
Allowlist دقیق مقصدها.

نیازی نیست برای اثبات Finding، سایت Phishing واقعی ساخته شود.

Incident Response

اگر Open Redirect مدت زیادی Public بوده است، باید بررسی شود آیا Abuse قابل مشاهده وجود داشته است یا خیر.

Logهای مناسب ممکن است شامل:

Destination Host،

Request Time،

Source IP،

User ID در صورت وجود،

و Endpoint مورد استفاده

باشند.

اگر Open Redirect در OAuth یا Reset Password Flow قرار داشته است، Scope Incident باید گسترده‌تر بررسی شود.

همچنین Landing Domainهای مشکوک مشاهده‌شده می‌توانند در Threat Intelligence داخلی ثبت شوند.

آیا حذف Parameter کافی است؟

اگر Redirect Feature دیگر لازم نیست، حذف آن بهترین گزینه است.

اما باید تمام Entry Pointها بررسی شوند.

ممکن است همان Helper Function در چند Endpoint دیگر استفاده شود.

Fix حرفه‌ای بهتر است در سطح Shared Redirect Utility انجام شود، نه فقط یک Controller.

سپس Regression Test اضافه شود.

Regression Test برای Open Redirect

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

Path داخلی مجاز است.

Host خارجی Reject می‌شود.

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

Scheme نامعتبر Reject می‌شود.

Scheme-relative URL رد می‌شود.

URL Encoding باعث Bypass نمی‌شود.

Upper/Lowercase رفتار صحیح دارد.

Redirect Mapping ناشناخته Fail Closed می‌شود.

OAuth Callback فقط URI ثبت‌شده را می‌پذیرد.

این Testها باید در CI/CD اجرا شوند.

Defense in Depth

یک معماری خوب می‌تواند چند Layer داشته باشد:

User Input
    ↓
Destination ID
    ↓
Server-side Mapping
    ↓
URL Parser
    ↓
Allowlist
    ↓
Redirect Utility
    ↓
Logging

اگر یکی از Layerها اشتباه شود، Layer دیگر ممکن است مانع Redirect غیرمجاز شود.

Open Redirect و Secure by Design

بهترین Fix همیشه اضافه کردن Regex به Code موجود نیست.

گاهی باید API را تغییر داد.

بد:

redirect(url)

بهتر:

redirect(destination_id)

این تغییر Interface باعث می‌شود Caller اصولاً نتواند URL Arbitrary وارد کند.

Secure by Design یعنی ایجاد APIهایی که استفاده ناامن از آنها سخت باشد.

سؤالات متداول درباره Open Redirect

Open Redirect چیست؟

Open Redirect یا ریدایرکت باز زمانی رخ می‌دهد که Application مقصد Redirect را از User Input دریافت و بدون Validation کافی Browser را به همان مقصد هدایت کند. این ضعف با CWE-601 شناخته می‌شود.

Open Redirect چه خطراتی دارد؟

مهم‌ترین خطر مستقل آن Phishing است، زیرا Link می‌تواند ابتدا از Domain معتبر سایت شروع شود. Open Redirect همچنین ممکن است در زنجیره OAuth، Bypass Validation یا سایر حملات نقش کمکی داشته باشد.

CWE مربوط به Open Redirect چیست؟

CWE-601 با عنوان URL Redirection to Untrusted Site ('Open Redirect').

Open Redirect در OWASP Top 10:2025 کجاست؟

CWE-601 در فهرست CWEهای مرتبط با A01:2025 Broken Access Control قرار دارد.

آیا هر Redirect یک Vulnerability است؟

خیر. Redirect یک قابلیت استاندارد HTTP است. Vulnerability زمانی ایجاد می‌شود که Destination غیرقابل‌اعتماد بدون Validation مناسب قابل کنترل باشد.

HTTP Location چیست؟

Location Header مقصد Redirect را مشخص می‌کند و معمولاً در Responseهای 3xx استفاده می‌شود. Browser می‌تواند براساس این مقدار به URI جدید مراجعه کند.

چه Parameterهایی ممکن است Open Redirect داشته باشند؟

نام‌هایی مانند next، redirect، url، return، continue و destination رایج‌اند، اما وجود آنها به‌تنهایی Vulnerability نیست. Data Flow و Validation باید بررسی شوند.

آیا startsWith("https://example.com") امن است؟

برای Security Validation بهتر است URL با Parser استاندارد Parse و Scheme، Host و Port به‌صورت Semantic بررسی شوند. Prefix Comparison خام می‌تواند Boundary واقعی URL را به‌درستی مدل نکند.

آیا Regex برای جلوگیری از Open Redirect کافی است؟

نه لزوماً. Parsing URL پیچیدگی‌های زیادی دارد. بهتر است ابتدا از URL Parser استاندارد استفاده کنید و سپس Componentهای Parseشده را با Allowlist بررسی کنید.

Allowlist بهتر است یا Denylist؟

برای Redirect Destination معمولاً Allowlist انتخاب امن‌تری است. OWASP و MITRE نیز Accept Known Good را توصیه می‌کنند.

بهترین روش جلوگیری از Open Redirect چیست؟

در صورت امکان URL کامل را از User دریافت نکنید. از Destination ID یا Path داخلی استفاده کنید و Server مقصد را تعیین کند. OWASP این رویکرد را از مهم‌ترین Mitigationها می‌داند.

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

در Open Redirect، Destination معمولاً از Parameter یا داده Application گرفته می‌شود. در Host Header Injection، Domain یا Authority از Host Header غیرقابل‌اعتماد مشتق می‌شود.

Open Redirect با SSRF چه تفاوتی دارد؟

Open Redirect Browser یا Client را به مقصد دیگری می‌فرستد؛ SSRF باعث می‌شود Server به مقصد دیگری Request ارسال کند. با این حال Open Redirect می‌تواند در برخی معماری‌ها بخشی از SSRF Chain باشد.

Open Redirect با XSS یکی است؟

خیر. XSS معمولاً اجرای JavaScript در Origin سایت را ممکن می‌کند، در حالی که Open Redirect User را به URL دیگری منتقل می‌کند.

آیا Open Redirect برای OAuth خطرناک است؟

بله، Context OAuth می‌تواند Impact آن را افزایش دهد. اگر Redirect URI یا یکی از Endpointهای مورد اعتماد Client دارای Open Redirect باشد، ممکن است Authorization Flow تحت تأثیر قرار گیرد.

آیا HTTPS از Open Redirect جلوگیری می‌کند؟

خیر. HTTPS ارتباط را رمزنگاری می‌کند، اما یک HTTPS Endpoint همچنان می‌تواند User را به Domain خارجی Redirect کند.

آیا CSP از Open Redirect جلوگیری می‌کند؟

CSP برای کنترل منابع و اجرای Content در Browser طراحی شده و جای Destination Validation را نمی‌گیرد.

آیا WAF مشکل را حل می‌کند؟

WAF می‌تواند لایه مکمل باشد، اما Root Cause داخل Logic برنامه است. مقصد باید توسط Application یا Infrastructure براساس Policy معتبر Validation شود.

Open Redirect در WordPress چگونه جلوگیری می‌شود؟

برای Redirect داخلی بهتر است از wp_safe_redirect() استفاده شود. این Function با کمک wp_validate_redirect() Host مقصد را بررسی می‌کند. پس از Redirect نیز معمولاً باید exit اجرا شود.

تفاوت wp_redirect و wp_safe_redirect چیست؟

wp_redirect() Redirect عمومی انجام می‌دهد و Host مقصد را الزاماً به Host سایت محدود نمی‌کند. wp_safe_redirect() مقصد را برای Redirect محلی Validate می‌کند.

آیا Redirect خارجی همیشه ممنوع است؟

خیر. بعضی Business Flowها واقعاً به Redirect خارجی نیاز دارند. در این حالت Destinationهای مجاز باید مشخص و Allowlist شوند.

آیا Open Redirect همیشه Severity بالا دارد؟

خیر. Severity به Context بستگی دارد. Open Redirect ساده ممکن است Low باشد، اما اگر در OAuth، Authentication یا Flow دارای Token حساس باشد Impact می‌تواند بسیار بیشتر شود.

جمع‌بندی

Open Redirect یا ریدایرکت باز در ظاهر Vulnerability ساده‌ای است: Application مقصد Redirect را از User دریافت می‌کند و بدون Validation کافی همان Destination را به Browser می‌دهد.

اما همین رفتار ساده می‌تواند مرز اعتماد سایت را تضعیف کند.

کاربر Linkی را مشاهده می‌کند که با Domain معتبر شروع می‌شود، اما چند لحظه بعد در Domain دیگری قرار دارد.

به همین دلیل Phishing یکی از شناخته‌شده‌ترین پیامدهای Open Redirect است.

MITRE این Weakness را با CWE-601 ثبت کرده و OWASP نیز آن را در مجموعه ریسک‌های Broken Access Control در Top 10:2025 قرار داده است.

با این حال خطر واقعی Open Redirect فقط Phishing مستقیم نیست.

در معماری‌های مدرن ممکن است Redirector مورد اعتماد وارد OAuth، Authentication، SSO، SSRF Protection، Tracking یا سایر Trust Decisionها شود.

در چنین شرایطی Open Redirect می‌تواند به یک Building Block مهم برای Exploit Chain تبدیل شود.

بهترین روش جلوگیری از Open Redirect این است که Application تا حد امکان اصلاً URL کامل را از User نپذیرد.

اگر Redirect به چند Destination محدود نیاز دارد، User باید ID یا Name کوتاهی ارسال کند و Server URL نهایی را از Mapping مورداعتماد انتخاب کند.

اگر فقط Redirect داخلی لازم است، Destination به Relative Path معتبر محدود شود.

اگر Redirect خارجی یک Business Requirement است، URL باید با Parser استاندارد Parse شود و Scheme، Host، Port و سایر Componentهای مرتبط با Allowlist مشخص مقایسه شوند.

Validationهای String-Based مانند contains، Prefix Matching ساده یا Denylist چند Domain قابل اتکا نیستند.

برای WordPress نیز Pluginها و Themeهای سفارشی باید Destination User-Controlled را مستقیماً وارد wp_redirect() نکنند. برای Redirect محلی، wp_safe_redirect() و wp_validate_redirect() ابزارهای استاندارد مناسب‌تری هستند و WordPress به‌صورت رسمی Host مقصد را در این مسیر بررسی می‌کند.

در نهایت مهم‌ترین سؤال هنگام بررسی هر Redirect این است:

«آیا Application خودش تصمیم می‌گیرد User مجاز است به کجا منتقل شود، یا این تصمیم را بدون Validation به داده‌ای واگذار کرده که User کنترل می‌کند؟»

اگر Destination نهایی عملاً توسط Client تعیین می‌شود، Redirect Logic باید به‌عنوان یک Trust Boundary امنیتی بازبینی شود.

مطالب مرتبط