我有一个旧的论坛脚本,该脚本允许用户注入愚蠢的javascript代码,因为该论坛脚本无法处理多次经过url编码的传入数据,因此,我试图弄清楚如何urldecode()
传入变量一次又一次,直到传入的变量中找不到更多的url编码的字符。
我也在尝试对html实体做同样的事情,但这似乎更加复杂,因为每次处理一个html实体时,字符串大小都会发生变化,而刚解码的html实体可能是另一个html实体的一部分这也需要解码。
无论如何...我想我需要将url解码器置于while()
循环中,并在变量上继续运行urldecode()
,直到对变量进行完全url解码为止,但是我很难时间来思考如何实现这一目标而又不会陷入永无止境的while()
循环中。
答案 0 :(得分:-1)
您的论坛脚本不应解码任何内容,而应在发送回文本时对其进行适当的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>';
}