我想过滤我网站上的用户输入并仅启用<iframe>
标签,用户将能够使用这些标签在他们的帖子中添加视频(如 youtube 和 vimeo)。
我的第一个想法是在其中使用strip_tags()
和启用<iframe>
标签。但后来我在这里读到了一篇关于这个功能的文章:
Reddit 上的文章
所以我认为使用它是个坏主意,因为你可以获得 XSS。
我怎么解决这个问题 ?
更新:我想要一个在这种情况下不会过度杀伤的解决方案。
我想过滤我网站上的用户输入并仅启用<iframe>
标签,用户将能够使用这些标签在他们的帖子中添加视频(如 youtube 和 vimeo)。
我的第一个想法是在其中使用strip_tags()
和启用<iframe>
标签。但后来我在这里读到了一篇关于这个功能的文章:
Reddit 上的文章
所以我认为使用它是个坏主意,因为你可以获得 XSS。
我怎么解决这个问题 ?
更新:我想要一个在这种情况下不会过度杀伤的解决方案。
也许不是允许人们发布 HTML,您可以在输入中搜索可能是 YouTube 视频链接的内容,然后自己拼接代码。
我今天早些时候在 StackOverflow 上找到了这段代码: 如何使用正则表达式在字符串中找到所有 YouTube 视频 ID?
它在字符串中搜索 YouTube URL,并用链接替换它们。下面是代码的修改版本,将 URL 替换为<iframe/>
s
// Linkify youtube URLs which are not already links.
// From https://stackoverflow.com/questions/5830387/php-regex-find-all-youtube-video-ids-in-string
function linkifyYouTubeURLs($text) {
$text = preg_replace('~
# Match non-linked youtube URL in the wild. (Rev:20111012)
https?:// # Required scheme. Either http or https.
(?:[0-9A-Z-]+\.)? # Optional subdomain.
(?: # Group host alternatives.
youtu\.be/ # Either youtu.be,
| youtube\.com # or youtube.com followed by
\S* # Allow anything up to VIDEO_ID,
[^\w\-\s] # but char before ID is non-ID char.
) # End host alternatives.
([\w\-]{11}) # $1: VIDEO_ID is exactly 11 chars.
(?=[^\w\-]|$) # Assert next char is non-ID or EOS.
[?=&+%\w-]* # Consume any URL (query) remainder.
~ix',
'
<iframe width="560" height="315" src="http://www.youtube.com/embed/$1"></iframe>
',
$text);
return $text;
}
你可以像这样实现它:
<?php
$text = 'This is my comment. It contains an XSS attack!:
<script type="text/javascript">
alert(\'bam\');
</script>
I learned about XSS on YouTube:
http://www.youtube.com/watch?v=i38LMZyKIqI
';
// Sanitize XSS (e.g.: convert '<' to '<')
$output = htmlspecialchars($text);
$pattern = [];
$output = linkifyYouTubeURLs($output);
// Add natural line breaks
$output = nl2br($output);
echo $output;
?>
XSS 攻击被阻止,但 YouTube 链接被转换为视频。您可能可以进一步修改它以与 Vimeo 和其他主要视频提供商合作。
以下是实际代码:
你可以试试这个:
$out = preg_replace("#<(?!/?iframe[ >])#i","<",$in);
但是请记住,用户可以将事件处理程序放在 iframe 标记上以引发某种 XSS。