摘要:本文是《DVWA从入门到精通》系列的第十七篇,带你全面掌握Open HTTP Redirect(开放重定向)模块的攻防全流程。从HTTP重定向的基本原理出发,逐步讲解Low、Medium、High三个级别的攻击手法与源码分析,并深入探讨Impossible级别的终极防御方案。文章包含绝对URL与相对路径的绕过、协议头过滤的多种绕过技巧、参数注入绕过、以及严格白名单防御等核心技术,让你真正做到"知其然更知其所以然"。
一、什么是开放重定向?
1.1 重定向的基本原理
HTTP重定向是Web应用中非常常见的功能------当你在浏览器中访问一个URL时,服务器除了直接返回网页内容,还可以告诉你:"这个资源不在这儿,你去另一个地方找吧"。服务器会返回一个3xx系列的状态码 (如302 Found),并在响应头中加上Location: 新的URL,浏览器看到这个响应后会自动跳转到新的地址。
这个过程本身是完全合法且必要的,比如:
-
网站改版换域名
-
用户登录后跳回原来访问的页面
-
短链接服务跳转到目标地址
1.2 开放重定向漏洞的本质
开放重定向(Open Redirect) 漏洞的根源在于:应用程序允许用户通过参数(如?redirect=)控制跳转的目标地址,但没有对这个地址进行严格的检查和限制。
用一个生活化的例子来理解:
你家小区门禁很严,陌生人进不来。但你家有个后门,门上贴了个纸条写着"推开门就能到XX地方"。攻击者不需要破解门禁,只需要把纸条上的地址改成"到我的陷阱屋",然后骗一个小区居民去推那扇门。居民一看是小区内部的后门,毫无防备地推开,结果就中招了。
开放重定向就是这个"后门"------网站本身是安全的(门禁很严),但重定向功能(后门上的纸条)被攻击者篡改了。
从技术角度来看:
当Web应用程序接受不受信任的输入时,可能会发生未经验证的重定向和转发,这可能导致Web应用程序将请求重定向到包含在不受信任输入中的URL。攻击者可以将不受信任的URL输入修改为恶意网站,从而成功发起网络钓鱼诈骗并窃取用户凭据。
1.3 开放重定向的危害
虽然开放重定向本身通常被归类为**"中危"** 漏洞,但它在实际攻击链中扮演着至关重要的角色:
| 危害 | 说明 |
|---|---|
| 钓鱼攻击 | 攻击者构造一个看起来完全合法的链接(域名是可信的),用户点击后却被带到高仿的钓鱼页面 |
| 恶意软件分发 | 跳转的终点可以是一个自动下载恶意程序的页面 |
| 绕过安全检测 | 一些安全软件会检查链接的域名是否在黑名单,攻击者先用白名单域名做第一次跳转,绕过检测 |
| 信任滥用 | 用户看到的是来自可信域名的URL,降低了警惕性 |
| 会话劫持 | 结合其他漏洞,重定向可用于窃取用户的会话令牌 |
1.4 常见触发场景
开放重定向漏洞通常出现在以下场景:
-
登录后的跳转功能(如
/login?redirect=/dashboard) -
外部链接的跳转页面(如
/goto?url=...) -
OAuth认证的回调URL
-
下载资源的重定向
-
短链接服务
二、准备工作
2.1 靶场环境
确保DVWA已部署并正常运行:
-
访问地址:
http://你的服务器IP/dvwa/login.php -
使用
admin/password登录
2.2 必备工具
| 工具 | 用途 |
|---|---|
| 浏览器(Chrome/Firefox) | 访问靶场,观察跳转行为 |
| Burp Suite | 抓包分析、修改请求参数(Medium/High级别必需) |
2.3 基础知识储备
-
理解HTTP状态码(3xx系列)
-
了解URL的组成部分(协议、域名、路径、参数)
-
了解
header("location: ...")函数的工作原理
三、Low级别:毫无防护的"裸奔"状态
3.1 安全级别设置
将DVWA Security设置为 Low 级别,然后进入 Open HTTP Redirect 模块。
3.2 界面观察
Open HTTP Redirect模块的页面显示了两个链接------"Quote 1"、"Quote 2"。点击任意一个链接,页面会跳转到一个显示引文的页面,同时URL中会出现redirect参数。

例如,点击"Quote 1"后,地址栏变为:

3.3 源码分析
查看Low级别的核心代码:
php
<?php
if (array_key_exists ("redirect", $_GET) && $_GET['redirect'] != "") {
header ("location: " . $_GET['redirect']);
exit;
}
http_response_code (500);
?>
<p>Missing redirect target.</p>
<?php
exit;
?>
这段代码存在致命的开放重定向漏洞:
| 缺陷 | 说明 |
|---|---|
| 无任何过滤 | 不检查redirect参数的值是否合法 |
| 无白名单/黑名单 | 不限制重定向的目标范围 |
| 直接信任用户输入 | 用户说什么就跳转到哪里 |
| 无协议验证 | 不检查是否跳转到外部域名 |
3.4 攻击方法:直接跳转到任意网站
由于Low级别没有任何防护,攻击者可以直接将redirect参数修改为任意URL。
第一步:构造恶意URL
在浏览器地址栏中输入:
php
http://10.0.0.149/vulnerabilities/open_redirect/source/low.php?redirect=https://www.baidu.com
第二步:观察结果
页面立即跳转到了百度首页。

第三步:构造钓鱼链接
攻击者可以将这个链接伪装成合法的DVWA链接发给受害者:
php
http://10.0.0.149/vulnerabilities/open_redirect/source/low.php?redirect=//10.0.0.149/test.html
放心点击,结果被带到了钓鱼网站(//10.0.0.149/test.html)。

3.5 Low级别总结
| 缺陷 | 说明 |
|---|---|
| 无任何过滤 | 用户输入直接被用作重定向目标 |
| 可跳转到任意外部URL | 包括钓鱼网站、恶意软件站点 |
| 高危漏洞 | 可被用于大规模钓鱼攻击 |
四、Medium级别:协议头过滤的"第一次尝试"
4.1 安全级别设置
将DVWA Security切换为 Medium 级别。
4.2 观察变化
在Medium级别下,尝试Low级别的方法(直接输入https://www.baidu.com),发现被阻止了------页面显示"Absolute URLs not allowed"(不允许绝对URL)。

4.3 源码分析
查看Medium级别的核心代码:
php
<?php
if (array_key_exists ("redirect", $_GET) && $_GET['redirect'] != "") {
if (preg_match ("/http:\/\/|https:\/\//i", $_GET['redirect'])) {
http_response_code (500);
?>
<p>Absolute URLs not allowed.</p>
<?php
exit;
} else {
header ("location: " . $_GET['redirect']);
exit;
}
}
http_response_code (500);
?>
<p>Missing redirect target.</p>
<?php
exit;
?>
Medium级别的变化:
| 改进 | 说明 |
|---|---|
| 增加了协议头过滤 | 使用正则表达式匹配http://和https:// |
4.4 正则表达式的局限
Medium级别只过滤了以http://或https://开头的绝对URL,但存在多种绕过方式:
| 防护措施 | 存在缺陷 | 危害 |
|---|---|---|
过滤http://、https://完整协议头 |
未拦截//协议相对 URL,过滤逻辑简陋 |
仍可跳转任意外网,用于网络钓鱼 |
| 仅黑名单过滤关键词 | 无域名白名单、无完整 URL 解析校验 | 中危漏洞,防护不彻底 |
4.5 攻击方法:双斜杠协议继承
攻击者可以使用双斜杠// :
php
http://10.0.0.149/vulnerabilities/open_redirect/source/medium.php?redirect=//www.baidu.com
浏览器会继承当前页面的协议 (http或https),自动补全为http://www.baidu.com或https://www.baidu.com。
4.6 Medium级别总结
| 防护改进(Medium) | 防护原理 | 局限性 / 绕过方式 |
|---|---|---|
正则黑名单拦截 http://、https:// |
使用正则匹配完整协议头,禁止绝对 URL 跳转,拦截带 http/https 的外网地址 | 1. 协议相对 URL //域名 可直接绕过,无协议标识不触发正则匹配2. 仍无域名白名单、无路径校验,跳转目标完全可控 |
五、High级别:白名单参数的"路径限制"
5.1 安全级别设置
将DVWA Security切换为 High 级别。
5.2 观察变化
在High级别下,尝试Medium级别的各种绕过方法(www.baidu.com、//www.baidu.com),发现都被阻止了。
5.3 源码分析
查看High级别的核心代码:
php
<?php
if (array_key_exists ("redirect", $_GET) && $_GET['redirect'] != "") {
if (strpos($_GET['redirect'], "info.php") !== false) {
header ("location: " . $_GET['redirect']);
exit;
} else {
http_response_code (500);
?>
<p>You can only redirect to the info page.</p>
<?php
exit;
}
}
http_response_code (500);
?>
<p>Missing redirect target.</p>
<?php
exit;
?>
High级别的变化:
| 改进 | 说明 |
|---|---|
| 简易白名单校验 | 强制要求 redirect 参数字符串内必须包含 info.php 子串 |
| strpos () 包含匹配检测 | 仅校验是否存在目标字符串,不校验域名、路径前后位置 |
| 非法地址拦截 | 不携带 info.php 的任意跳转地址直接返回 500 错误拒绝 |
5.4 白名单的漏洞:内嵌URL绕过
High 级别仅要求字符串中存在 info.php,未限制 info.php 出现的位置、不校验整体地址是站内还是外网 。 本漏洞利用方式为外网 URL 内嵌合法关键字绕过 :在外部网址中插入info.php子串,满足 strpos 检测直接跳转外网。
5.5 攻击方法一:外部 URL 内嵌关键字绕过
构造可利用Payload:
php
http://10.0.0.149/vulnerabilities/open_redirect/source/high.php?redirect=https://www.baidu.com/?param=info.php
原理分析:
-
redirect 完整值:
https://www.baidu.com/?param=info.php -
strpos 检测到字符串包含
info.php,校验直接放行; -
服务端将完整外网链接传入
Location响应头; -
浏览器直接跳转百度外网,成功突破限制实现外部跳转。
结果:成功跳转到外部网站!
5.6 攻击方法二:查询字符串注入
Payload:
http://10.0.0.149/vulnerabilities/open_redirect/source/high.php?redirect=info.php%3Fid%3D1%26next%3Dhttps://www.baidu.com
URL 解码后: info.php?id=1&next=https://www.baidu.com
原理与真实效果:
-
high.php 通过 strpos 检测到
info.php,放行并重定向到站内的 info.php; -
DVWA 原生
info.php仅为信息展示页面,无读取 next 参数的跳转代码; -
页面只会停留在站内,不会自动跳转外部百度,该利用方式在原生 DVWA 环境下完全无效。
5.7 High级别总结
| 防御机制 | 作用 | 绕过方法 & 局限性 |
|---|---|---|
| 强制 redirect 包含 info.php | 拦截不含该字符串的跳转地址 | 1. 外网 URL 参数内嵌 info.php,一步直接跳转外网(稳定可用)2. info.php 拼接跳转参数仅理论可行,DVWA 原生 info 无跳转逻辑,无法出网 |
| strpos 宽松匹配白名单 | 仅校验关键字是否存在,不校验整体域名 | 只做字符串包含检测,不区分站内 / 外部域名,防护逻辑存在重大缺陷 |
六、Impossible级别:终极防御方案
6.1 安全级别设置
将DVWA Security切换为 Impossible 级别。
6.2 源码分析
查看Impossible级别的核心代码:
php
<?php
$target = "";
if (array_key_exists ("redirect", $_GET) && is_numeric($_GET['redirect'])) {
switch (intval ($_GET['redirect'])) {
case 1:
$target = "info.php?id=1";
break;
case 2:
$target = "info.php?id=2";
break;
case 99:
$target = "https://digi.ninja";
break;
}
if ($target != "") {
header ("location: " . $target);
exit;
} else {
?>
Unknown redirect target.
<?php
exit;
}
}
?>
Missing redirect target.
6.3 Impossible级别的严格白名单防御
Impossible级别采用了最严格的防御策略:
| 防御层 | 技术手段 | 作用 |
|---|---|---|
| 第一层 | 强类型校验 is_numeric() |
仅允许数字传入 redirect 参数,直接拦截所有字符串、URL、带特殊符号输入 |
| 第二层 | Switch数字映射固定跳转地址 | 输入数字1/2/99,一对一绑定写死的跳转目标,无任何自定义拼接 |
| 第三层 | 其余全部拦截 | 非数字、不在case内的数字,均提示未知跳转目标,拒绝执行重定向 |
6.4 为什么Impossible级别无法被绕过?
| 攻击方式 | Impossible 防护逻辑 | 能否成功利用 |
|---|---|---|
| 直接输入外部 URL(baidu 等) | 先校验is_numeric(),字符串直接拦截 |
❌ 完全失效 |
| High 级别绕过(URL 内嵌 info.php) | payload 是字符串,无法通过数字校验 | ❌ 完全失效 |
| // 省略协议头、URL 编码、参数拼接 | 全部属于字符串,第一层校验直接拦截 | ❌ 完全失效 |
| 多参数污染 HPP、嵌套查询串 | 参数值非数字,无法进入 switch 逻辑 | ❌ 完全失效 |
精确白名单匹配 是防御开放重定向的唯一正确方式------只允许跳转到预定义的安全目标,拒绝一切其他输入。
七、防御开放重定向的最佳实践
通过DVWA四个级别的对比,我们可以总结出防御开放重定向的最佳实践:
7.1 必须实施的防御措施
| 措施 | 说明 | 优先级 |
|---|---|---|
| 固定映射 / 严格白名单 | 预定义有限跳转标识,一一绑定目标地址,禁止用户直接传入 URL | ⭐⭐⭐⭐⭐ |
| 拒绝用户直接传入 URL | 不把用户输入直接拼入 Location 响应头 | ⭐⭐⭐⭐⭐ |
| 禁用包含式匹配(strpos) | 禁止仅检测关键字存在,极易被绕过 | ⭐⭐⭐⭐⭐ |
| 校验域名归属 | 若允许外跳,使用可信域名列表白名单,禁止任意外网 | ⭐⭐⭐⭐ |
7.2 推荐的辅助措施
| 措施 | 说明 | 优先级 |
|---|---|---|
| 优先站内相对路径 | 限制仅站内页面跳转,彻底杜绝外网跳转风险 | ⭐⭐⭐⭐ |
| 跳转确认页面 | 跳转至外部站点前增加弹窗 / 页面提示,告知用户即将离开本站 | ⭐⭐⭐ |
| 重定向行为日志记录 | 记录跳转参数、客户端 IP,方便事后审计溯源 | ⭐⭐ |
| 限制跳转次数、有效期 | 防止恶意批量钓鱼链接分发 | ⭐⭐ |
7.3 常见误区
在实际开发中,以下做法不能有效防御开放重定向:
-
仅黑名单过滤
http://、https://,可被//协议相对 URL 绕过(Medium 级别缺陷); -
使用
strpos做关键字包含校验,仅要求字符串携带指定文本(High 级别缺陷); -
直接接收完整 URL 作为参数,不做任何域名校验(Low 级别高危缺陷);
-
URL 编码、正则过滤关键词,存在大量变形绕过手段。
八、开放重定向的实战检测思路
在实际的渗透测试中,如何快速发现开放重定向漏洞?
8.1 检测步骤
-
抓包寻找页面跳转相关 GET/POST 参数;
-
传入外部 URL(https://baidu.com)测试是否直接跳转;
-
若拦截完整 http 协议,使用
//baidu.com协议相对地址绕过测试; -
若要求包含指定关键字,在外网 URL 路径 / 参数内拼接关键字测试;
-
若仅接收数字 / 固定标识,尝试枚举所有映射值,判断是否存在可控外跳;
-
观察是否存在二次跳转页面,可拼接跳转参数实现间接出网。
8.2 常见参数名
| 参数名 | 说明 |
|---|---|
| redirect | 最通用跳转参数 |
| url、target、dest、destination | 页面跳转、文件跳转常用 |
| return、return_to、continue、next | 登录 / 注册完成回调跳转 |
| goto、link | 简易页面跳转 |
| callback | OAuth、第三方登录回调高危参数 |
8.3 常见绕过手法汇总
| 防护类型 | 绕过方法 | 对应级别 |
|---|---|---|
| 无任何过滤 | 直接传入完整外部 URL | Low |
| 黑名单过滤 http/https 协议头 | 双斜杠//协议相对地址、特殊协议变形 |
Medium |
| strpos 关键字包含校验(需携带指定字符串) | 在外部 URL 的查询参数 / 路径中内嵌指定关键字 | High |
| 数字强校验 + 固定地址映射白名单 | 不存在可用绕过方式 | Impossible |
九、总结
本文完整完成了开放重定向漏洞的原理学习、分级实战与防御总结,系统掌握了该漏洞的完整攻防体系。我们首先理解了开放重定向的核心原理,即Web应用未对用户可控的跳转参数做严格校验,允许攻击者篡改重定向目标地址,进而实现跳转劫持,该漏洞主要危害为网络钓鱼、恶意程序分发、站点信任滥用及安全策略绕过,在社工攻击链中具备重要利用价值。在分级实战中,Low级别无任何过滤校验,攻击者可直接修改redirect参数跳转至任意外部恶意网址;Medium级别采用正则黑名单过滤http://与https://协议头,存在明显防护缺陷,可通过双斜杠协议相对地址等方式轻松绕过,并非可靠防护手段;High级别采用strpos字符串包含校验机制,要求参数必须携带info.php关键字,原文所述参数污染绕过方式并不成立,真实有效绕过方式为在外部URL中内嵌info.php关键字,欺骗服务端校验实现外网跳转;Impossible级别摒弃了不安全的字符串匹配逻辑,采用数字强类型校验+固定地址映射的终极白名单机制(并非in_array完全匹配),通过预设固定跳转标识绑定可信目标地址,完全杜绝用户可控篡改跳转目标的可能性,彻底修复开放重定向漏洞。最后本文总结了开放重定向的安全防御最佳实践,杜绝黑名单过滤、模糊包含匹配等不安全写法,坚持采用精准固定映射白名单、禁止用户直接控制跳转目标、校验可信域名范围等核心防护手段。开放重定向虽多为中危漏洞,但却是钓鱼社工攻击的核心跳板,依托可信域名降低用户警惕性,危害极大,生产环境中通过严格白名单限制、杜绝用户可控跳转参数的组合防护方式,可彻底根除该类漏洞风险。
**重要声明:**本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。
如果这篇文章帮你解决了实操上的困惑,别忘记点击点赞、分享 ,也可以留言告诉我你遇到的其它问题,我会尽快回复。你的关注是我坚持原创和细节共享的力量来源,谢谢大家。