2

我想允许用户通过 HTML 表单粘贴<embed><object>HTML 片段(视频播放器)。服务器端代码是 PHP。如何防止恶意粘贴代码、JavaScript 等?我可以解析粘贴的代码,但我不确定我是否能解释所有变化。有没有更好的办法?

4

3 回答 3

4

我不太确定参数EMBEDOBJECT采用什么参数,因为我从来没有真正处理过将媒体放在页面上(这实际上是一种令人震惊的想法),但我会采用 BB Code 方法并做类似的事情[embed url="http://www.whatever.com/myvideo.whatever" ...]然后您可以解析 URL 和其他任何内容,确保它们是合法的并制作您自己的<EMBED>标签。

编辑:好的,这样的事情应该没问题:

$youtube = '<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Z75QSExE0jU&hl=en&fs=1"></param> </param><embed src="http://www.youtube.com/v/Z75QSExE0jU&hl=en&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object>';

$blip = '<embed src="http://blip.tv/play/AZ_iEoaIfA" type="application/x-shockwave-flash" width="640" height="510" allowscriptaccess="always" allowfullscreen="true"></embed>';

preg_match_all("/([A-Za-z]*)\=\"(.+?)\"/", $youtube, $matches1);
preg_match_all("/([A-Za-z]*)\=\"(.+?)\"/", $blip, $matches2);
print '<pre>' . print_r($matches1, true). '</pre>';
print '<pre>' . print_r($matches2, true). '</pre>';

这将输出:

Array
(
[0] => Array
    (
        [0] => width="425"
        [1] => height="344"
        [2] => name="movie"
        [3] => value="http://www.youtube.com/v/Z75QSExE0jU&hl=en&fs=1"
        [4] => src="http://www.youtube.com/v/Z75QSExE0jU&hl=en&fs=1"
        [5] => type="application/x-shockwave-flash"
        [6] => allowfullscreen="true"
        [7] => width="425"
        [8] => height="344"
    )

[1] => Array
    (
        [0] => width
        [1] => height
        [2] => name
        [3] => value
        [4] => src
        [5] => type
        [6] => allowfullscreen
        [7] => width
        [8] => height
    )

[2] => Array
    (
        [0] => 425
        [1] => 344
        [2] => movie
        [3] => http://www.youtube.com/v/Z75QSExE0jU&hl=en&fs=1
        [4] => http://www.youtube.com/v/Z75QSExE0jU&hl=en&fs=1
        [5] => application/x-shockwave-flash
        [6] => true
        [7] => 425
        [8] => 344
    )
)

Array
(
[0] => Array
    (
        [0] => src="http://blip.tv/play/AZ_iEoaIfA"
        [1] => type="application/x-shockwave-flash"
        [2] => width="640"
        [3] => height="510"
        [4] => allowscriptaccess="always"
        [5] => allowfullscreen="true"
    )

[1] => Array
    (
        [0] => src
        [1] => type
        [2] => width
        [3] => height
        [4] => allowscriptaccess
        [5] => allowfullscreen
    )

[2] => Array
    (
        [0] => http://blip.tv/play/AZ_iEoaIfA
        [1] => application/x-shockwave-flash
        [2] => 640
        [3] => 510
        [4] => always
        [5] => true
    )
)

从那时起,它就非常简单了。对于像宽度/高度这样的东西,您可以使用它们来验证它们,is_numeric其余的您可以运行这些值htmlentities并从信息中构建您自己的<embed>标签。我很确定这将是安全的。您甚至可以使用来自 blip.tv 的链接制作完整的<object>YouTube(我认为它可以在更多地方使用),因为您将拥有所有必需的数据。

我相信您可能会看到来自其他视频共享网站的链接的一些怪癖,但这有望帮助您入门。祝你好运。

于 2008-10-19T07:55:15.117 回答
1

通过扫描输入的 HTML 可靠地检测到恶意代码的机会几乎为零。注入脚本的方法有很多(包括特定于浏览器的格式错误的 HTML),您将无法全部挑选出来。如果大型网络邮件提供商多年后仍在寻找新的漏洞,那么您就不可能做到这一点。

白名单比黑名单好。因此,您可以改为要求输入为 XHTML,并使用标准 XML 解析器对其进行解析。然后遍历 DOM 并检查每个元素和属性是否已知良好,如果一切正常,则序列化回 XHTML,它来自已知良好的 DOM,不应该是格式错误的。支持 Unicode 的适当 XML 解析器还应该免费过滤掉讨厌的“超长 UTF-8 序列”(影响 IE6 和旧 Opera 的安全漏洞)。

但是...如果您允许来自任何域的嵌入/对象,则您已经允许从外部域对您的页面进行完整的脚本访问,因此 HTML 注入是您最不必担心的。Flash 等插件很可能无需任何技巧即可执行 JavaScript。

因此,您应该将对象的来源限制在预先确定的已知良好域中。如果您已经这样做了,那么只允许用户选择视频提供者和剪辑 ID,然后将其转换为该提供者的正确、已知良好的嵌入代码,可能会更容易。例如,如果您使用类似 bbcode 的标记,则让用户包含 YouTube 剪辑的传统方式是 [youtube]Dtzs7DSh[/youtube]。

于 2008-10-19T09:08:44.390 回答
0

以下是来自 blip.tv 的粘贴代码示例:

<embed src="http://blip.tv/play/AZ_iEoaIfA" type="application/x-shockwave-flash"    
  width="640" height="510" allowscriptaccess="always" allowfullscreen="true"></embed>

以下是您可能从 YouTube 获得的内容的示例:

<object width="425" height="344">
  <param name="movie" value="http://www.youtube.com/v/Z75QSExE0jU&hl=en&fs=1"></param>
  <param name="allowFullScreen" value="true"></param>
    <embed src="http://www.youtube.com/v/Z75QSExE0jU&hl=en&fs=1"
      type="application/x-shockwave-flash" allowfullscreen="true"
      width="425" height="344"></embed>
</object>
于 2008-10-19T08:12:50.603 回答