我有一个旧的论坛脚本,允许用户注入愚蠢的javascript代码,因为论坛脚本无法处理多次URL编码的传入数据,所以我试图弄清楚如何一次又一次地urldecode()
传入变量,直到在传入变量中找不到更多的url编码字符。
我也在尝试对 html 实体做同样的事情,但这似乎更复杂,因为每次处理一个 html 实体时,字符串大小都会发生变化,您刚刚解码的 html 实体可能是另一个 html 实体的一部分也需要解码。
无论如何。。。我想我需要将 url 解码器放在一个 while()
循环中,并继续urldecode()
变量上运行,直到变量完全 url 解码,但我很难弄清楚如何实现它而不会让自己陷入永无止境的while()
循环。
您的论坛脚本不应该解码任何内容,它应该在发送回文本时对文本进行正确的 HTML 编码。 如果我们想象这是您当前的视图脚本:
foreach($db->query("SELECT `author`,`message` FROM messages WHERE thread_id = ".((int)$thread_id)." ORDER BY date ASC",PDO::FETCH_ASSOC) as $message){
echo '<div style="message"><span style="message-author">'
.$message["author"].'</style>
'.$message["message"].'</div>';
}
(这个示例代码确实对JavaScript注入开放),你需要向它添加HTML编码,这可以像这样完成:
/**
* convert any string to valid HTML, as losslessly as possible, assuming UTF-8
*
* @param string $str
* @return string
*/
function hhb_tohtml(string $str): string {
return htmlentities ( $str, ENT_QUOTES | ENT_HTML401 | ENT_SUBSTITUTE | ENT_DISALLOWED, 'UTF-8', true );
}
foreach($db->query("SELECT `author`,`message` FROM messages WHERE thread_id = ".((int)$thread_id)." ORDER BY date ASC",PDO::FETCH_ASSOC) as $message){
echo '<div style="message"><span style="message-author">'
.hhb_tohtml($message["author"]).'</style>
'.hhb_tohtml($message["message"]).'</div>';
}
- 当通过 htmlentities() 运行输出(使用适当的参数)时,将 JavaScript 注入到视图页面应该是不可能的。