显示一个未编码的 HTTP Referer 标头是否容易受到 XSS 的攻击?

信息安全 xss 推荐人
2021-08-18 11:49:54

考虑以下 PHP 脚本(它可以是任何其他语言;为简单起见,我选择了 PHP):

<?php
echo $_SERVER['HTTP_REFERER'];
?>

是否容易受到 XSS 攻击?

当然,我可以使用 curl 向脚本发送请求并将引用者设置为<script>alert(document.cookie)</script>. 但是,至少某些浏览器似乎对引用者进行了编码,因此,例如,如果我将用户从以下 URL 重定向到该脚本:

http://example.com/<script>alert(document.cookie)</script>

浏览器对referer进行编码,结果PHP脚本输出:

http://example.com/%3Cscript%3Ealert(document.cookie)%3C/script%3E

有没有不编码referer的浏览器?如果没有,是否可以通过其他方式加以利用?

1个回答

RFC

RFC 1945 - 首先提到了引用者标头 - 指定引用者需要进行 URL 编码:

推荐人=“推荐人”“:”(absoluteURI | relativeURI)

absoluteURI = scheme ":" (uchar | reserved)
[...]
uchar = unreserved | 无保留地逃脱
= ALPHA | 数字 | 安全 | 额外 | 国家
转义 = "%" HEX HEX
保留 = ";" | "/" | “?” | “:” | "@" | "&" | “=” | “+”
额外=“!” | "
" | "'" | "(" | ")" | ","
安全 = "$" | "-" | "_" | “。”
不安全 = CTL | SP | <"> | "#" | "%" | "<" | ">"

像 7231 这样更新的 RFC 更难阅读,因为它们交叉引用了很多,但似乎它们并没有改变这条规则。

因此<根据相关的 RFC,需要对 URL 进行编码>"情况总是如此,因此即使是非常旧的浏览器也应该进行 URL 编码。

请注意,'它不需要编码——现代浏览器也没有编码——因此可以用于 XSS 攻击(例如<a href='[REFERER]'>go back</a>)。

在实践中

尽管 RFC 指定<>"需要进行 URL 编码,但为了以防万一,自己对引用者进行编码仍然是一个好主意。

浏览器应该遵循 RFC——Chrome 和 Firefox 等主流浏览器在这种情况下会这样做——但最好还是遵循最佳实践——即编码——以防某些浏览器不遵循,或者 RFC 发生变化将来(尽管不太可能)。