不安全的重定向本身不会导致SQL注入,真正风险在于重定向参数被二次解析并拼入SQL语句;修复关键是对所有可能流入数据库的用户输入(包括重定向参数)实施白名单校验或参数化查询。
不安全的重定向 本身不会导致 SQL注入 —— 这是两个独立的安全问题。如果你在整改报告或扫描工具中看到“因不安全的重定向导致SQL注入”,那大概率是误报,或者背后存在更隐蔽的逻辑耦合:重定向参数被拼接到 SQL 查询中,而未做任何处理。
真正要修复的,不是重定向本身,而是那个被重定向逻辑间接使用的、未经防护的用户输入。
Location 头里的参数进了 WHERE 子句?这是最典型的“伪装成重定向问题”的 SQL 注入场景。比如 PHP 中常见写法:
$redirect_url = $_GET['next'];header("Location: " . $redirect_url);
看起来只是跳转,但如果后续某处代码把 next 的值(比如 user_id=123)直接解析、提取、再拼进 SQL:
parse_str($_GET['next'], $params);$id = $params['user_id']; // 没过滤$sql = "SELECT * FROM users WHERE id = " . $id; // 危险!
此时攻击者可构造:?next=user_id=1%20OR%201=1 → 解析后 $id 变成 1 OR 1=1 → SQL 被篡改。
header("Location: ...") 本身有问题,而是它成了恶意输入的“运输通道”$_GET['next'] 等跳转参数必须白名单校验所有用于重定向的参数,只要可能被后续逻辑读取并参与数据库操作,就必须严格限制其格式和内容:
/dashboard、/profile),拒绝带查询参数的 URL id 且为正整数:if (!is_numeric($_GET['id']) || $_GET['id'] < 1) die(); parse_str()、urldecode()、http_build_query() 等函数反向解析重定向参数再喂给 SQL ['a' => 101, 'b' => 202]),避免裸露原始值即使你确认某个变量“只是从 next 来的”,只要它最终进了 SQL,就必须走参数化流程:
$stmt = $pdo->prepare("SELECT * FROM logs WHERE redirect_token = ?");$stmt->execute([$_GET['token']]);
psycopg2 示例:cursor.execute("SELECT * FROM sessions WHERE ref = %s", (request.args.get('ref'),))
别信“这个参数我只用了一次”“它只是跳转用的”——只要代码里出现 WHERE + 用户输入,就触发防护义务。
重定向本身不执行 SQL,但它是攻击者最常利用的“输入入口”。修复重点从来不在 header() 怎么写,而在于:所有从 URL、表单、Header 等渠道进来的值,只要可能流到数据库,就必须被参数化或白名单拦截——无论它中间经过几次赋值、是否看起来“只是跳转用”。
最容易被忽略的,就是那些藏在重定向参数背后的、被 parse_str 或正则提取出来的子字段。