清理用户输入但启用iframe

时间:2012-09-13 14:21:04

标签: php html xss

我想在我的网站上过滤用户输入并仅启用<iframe>标记,用户可以使用这些标记在其帖子中添加视频(例如youtube和vimeo)。

我的第一个想法是使用strip_tags()并在其中启用<iframe>标记。 但后来我在这里读了一篇关于这个功能的文章: Article on Reddit

所以我认为使用它是个坏主意因为你可以得到XSS。

我该如何解决这个问题?

更新:我想要的解决方案在这种情况下不会过度。

2 个答案:

答案 0 :(得分:1)

也许不是允许人们发布HTML,您可以在输入中搜索可能链接到YouTube视频的内容,然后自己拼接代码。

我今天早些时候在StackOverflow上找到了这段代码: How do I find all YouTube video ids in a string using a regex?

它会在字符串中搜索YouTube网址,并将其替换为链接。以下是使用<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 '&lt;')
$output = htmlspecialchars($text);

$pattern = [];

$output = linkifyYouTubeURLs($output);

//  Add natural line breaks
$output = nl2br($output);

echo $output;

?>

XSS攻击已停止,但YouTube链接会转换为视频。您可以进一步修改它以与Vimeo和其他主要视频提供商合作。

以下是行动中的代码:

http://codepad.viper-7.com/8w0h1F

答案 1 :(得分:0)

你可以试试这个:

$out = preg_replace("#<(?!/?iframe[ >])#i","&lt;",$in);

但请记住,用户可以在iframe代码上放置事件处理程序以导致某种XSS。