安全解析 Markdown 样式链接

Coc*_*ico 5 php regex xss markdown

我编写了一些代码来匹配和解析这种风格的 Markdown 链接:

[click to view a flower](http://www.yahoo.com/flower.html)
Run Code Online (Sandbox Code Playgroud)

我有这段代码,旨在提取链接文本,然后提取 url 本身,然后将它们粘贴到 A HREF 链接中。但我担心也许我错过了某人注入 XSS 的方法,因为我留下了相当多的字符。这安全吗?

$pattern_square = '\[(.*?)\]';
$pattern_round  = "\((.*?)\)";

$pattern = "/".$pattern_square.$pattern_round."/";

preg_match($pattern, $input, $matches);
$words = $matches[1];
$url   = $matches[2];

$words = ereg_replace("[^-_@0-9a-zA-Z\.]", "", $words);
$url   = ereg_replace("[^-A-Za-z0-9+&@#/%?=~_|!:.]","",$url);

$final = "<a href='$url'>$words</a>";
Run Code Online (Sandbox Code Playgroud)

它似乎工作正常,并且确实排除了一些包含分号和反斜杠的愚蠢 URL,但我不关心这些 URL。

Boa*_*ann 4

如果您已经传递了输入htmlspecialchars(您正在这样做,对吧?),那么链接就不可能包含任何可能导致 XSS 的字符。

如果您还没有通过 传递输入htmlspecialchars,那么在解析链接时执行什么过滤并不重要,因为您已经被搞砸了,因为人们可以在链接之外轻松包含任意 HTML 或 XSS。

此函数将在应用时安全地解析文本中的 Markdown 链接htmlspecialchars

function doMarkdownLinks($s) {
    return preg_replace_callback('/\[(.*?)\]\((.*?)\)/', function ($matches) {
        return '<a href="' . $matches[2] . '">' . $matches[1] . '</a>';
    }, htmlspecialchars($s));
}
Run Code Online (Sandbox Code Playgroud)

如果您需要做比这更复杂的事情,我建议您使用现有的解析器,因为这种事情很容易出错。