Open HTTP Redirect(开放 HTTP 重定向)是指网站未经验证,就将用户直接重定向到用户可控的 URL 地址上,本质是url跳转漏洞,多用于钓鱼。
漏洞原理:
-
应用程序通过 URL 参数(如
?redirect=目标地址)来决定跳转去向。 -
漏洞核心:如果程序没有校验这个
redirect参数是否为可信、内部的地址,攻击者就可以将其篡改为任意恶意网站。 -
危害:构造看似可信的官方链接,诱导用户点击后跳转到钓鱼网站,窃取账号密码。
Low
源码分析:
php
<?php
// 第一步:判断 URL 里有没有传 redirect 参数,并且不为空
if (array_key_exists("redirect", $_GET) && $_GET['redirect'] != "") {
// 第二步:直接跳转到用户传入的 redirect 地址
header("location: " . $_GET['redirect']);
// 跳转后立刻停止执行代码
exit;
}
// 如果没有传 redirect 参数,返回 500 错误
http_response_code(500);
?>
<p>Missing redirect target.</p>
<?php
exit;
?>
漏洞根源:服务器完全信任用户传入的任何地址,直接跳转,没有任何检查!
php
header("location: " . $_GET['redirect']);
构造payload
php
/DVWA/vulnerabilities/open_redirect/source/low.php?redirect=https://www.baidu.com
注意这里是low.php

成功跳转!!
Medium
源码分析:过滤了http://和https://(/i 不区分大小写)
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;
?>
使用协议相对url://www.baidu.com,浏览器会自动补全
php
DVWA/vulnerabilities/open_redirect/source/medium.php?redirect=//www.baidu.com

成功跳转!!
High
源码分析:用户传入的地址中,是否包含 info.php 这个字符串,而不是完全匹配
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;
?>
构造url
php
/DVWA/vulnerabilities/open_redirect/source/high.php?redirect=https://www.baidu.com/?x=info.php

成功跳转!!
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.