PHP urldecode 一个可以多次编码的字符串



我有一个旧的论坛脚本,允许用户注入愚蠢的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 注入到视图页面应该是不可能的。

最新更新