防范http响应头注入需严格校验重定向参数:仅允许白名单路径映射或可信https域名,清洗cr/lf及编码变体,优先使用框架安全重定向方法,并辅以waf拦截crlf序列。

关键在于不让用户输入直接进入响应头,尤其是 Location、Set-Cookie、Refresh 这类可被动态构造的头部字段。校验不是“检查有没有危险”,而是“只允许已知安全的值”。
只放行白名单中的跳转目标
重定向是最常见的攻击入口。不要拼接用户传来的 URL,而是映射到预设路径:
- 把
$_GET['redirect']的值当作键,查表匹配合法路径,如:['profile' => '/user/profile', 'dashboard' => '/home'] - 若需支持外部跳转,先用
parse_url()解析,验证scheme是https、host在可信域名列表中(如['example.com', 'api.example.com']) - 绝对避免
header('Location: ' . $_GET['url'])这类写法,哪怕加了urlencode()也不行——编码可能被绕过,且浏览器解码后仍会触发拆分
对 header() 参数做字符清洗
所有进 header() 的字符串,必须剔除 CR/LF 及其编码变体:
将针对 Pi、Claude Code、Codex、OpenCode、Gemini CLI 或 ACP harness 的自然语言请求路由至 OpenClaw ACP 运行时会话,或直接路由至 acpx-...
- 用
str_replace(['\r', '\n', "%0d", "%0a", "%0D", "%0A"], '', $input)直接清除 - 更稳妥的做法是配合正则白名单:只保留字母、数字、下划线、连字符、点号和斜杠(如用于路径),其余一律过滤或拒绝
- 不要依赖
filter_var($input, FILTER_SANITIZE_STRING)—— PHP 8.1+ 已弃用该常量,应改用preg_replace('/[^a-zA-Z0-9_.\-\/]/', '', $input)显式控制
用框架内置响应机制替代裸 header()
Laravel 的 response()->redirectTo()、Symfony 的 RedirectResponse 等,底层已自动剥离控制字符。手动构造响应头容易遗漏边界情况:
- 框架会在设置
Location前调用内部清洗逻辑,比如 Laravel 的validateUrl()方法会检查协议和主机 - 即使你写了
return redirect($_GET['next']),框架也会拦截并抛出异常,而不是静默执行 - 自研系统若无法迁移框架,至少封装一个
safe_header()函数,强制走清洗流程
加一层 WAF 规则兜底
代码层防护可能有疏漏,WAF 可拦截含 CRLF 序列的请求:
- 在 Nginx 或云 WAF 中配置规则,匹配请求参数中出现
%0d%0a、\r\n、%0D%0A等组合 - 重点监控
GET和POST中常用于跳转的参数名,如url、redirect、return、next - 规则动作设为阻断,并记录日志——这类请求基本无正常业务场景,直接拦截风险低










