如何在PHP中安全地接受粘贴的<embed />代码

时间:2008-10-19 07:51:39

标签: php validation embed

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

3 个答案:

答案 0 :(得分:4)

我不确定参数EMBEDOBJECT是什么,因为我从未真正处理过将媒体放在页面上的问题(这实际上是令人震惊的想法)但我会采用BB代码方法并执行[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(我认为可以在更多地方使用),因为您将获得所有必需的数据。

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

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分: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>