【问题标题】:Disable javascript entry into form禁用 javascript 进入表单
【发布时间】:2014-12-20 03:19:10
【问题描述】:

我正在为我的网页创建一个“HTML 编辑器”。目前,我只希望编辑器允许输入 HTML 和 CSS 元素以及 not Javascript(或 Jquery)。

我正在尝试找到一种方法来禁用使用 PHP 的 <script><script type="text/javascript"> </script>。但是当前的方式输出的结果很混乱!

        $content_in_before = str_replace('<script','',$content_in_before);
        $content_in_before = str_replace('script>','',$content_in_before);

编码也不是很好!

有没有更安全的编码方式,阻止所有类型的 Javascript 输入到这个表单中? (虽然仍然允许 CSS 和 HTML)?

提前致谢!

【问题讨论】:

  • strip_tags() 或许?
  • 这不会解决您的问题,您仍然可以通过事件属性添加 javascript,例如 onLoadonClick 等。如果您真的想确保没有上传任何脚本,请使用其他语言,例如降价或使用经过验证的库。
  • 使用 onLoad 和 onClick 等属性不用担心,因为您可以用它们做的事情很少。但是
  • 任何你可以在脚本标签中做的事情,你都可以在onLoad属性中做...

标签: javascript php jquery html


【解决方案1】:

我建议使用像HTML Purifier这样的清理库,因为仅仅剥离&lt;script&gt;标签不足以防止XSS攻击,因为JS可以使用onLoadonMouseOver等属性自动执行, onUnload

要删除标签并允许一些标签,您可以使用 PHP 的 strip_tags() 函数,但它不会去除属性,因此我建议使用 HTML 清理库。如果您能够运行它,也许最好的选择之一是 Google 的 Caja 库,尽管它是用 Java 编写的,所以它不能在共享托管环境中工作,但它可以托管在 Google 的 AppEngine 上。

此外,简单的正则表达式解决方案并不总是可靠的,因为即使是格式错误的标签仍然可以被解析。例如,&lt;script &gt; 不会被普通脚本标签的简单正则表达式检测捕获,除非它在标签名称后寻找空格。可以检查这一点,但使用已建立的库会节省您的时间,并且会给您带来久经考验的库的额外好处。

示例: Script Tags with Spaces producing an alert

【讨论】:

  • 非常感谢!我决定在页面上实现 HTML Purifier,它就像一个魅力!
  • 这是正确的做法。尽管可以编写一个正则表达式来替换属性,但这需要太多的工作,而且正则表达式不是正确的工具。
【解决方案2】:

你能给你一个像这样的正则表达式

echo preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', "", $var);

来源:https://stackoverflow.com/a/1886842/2046700

或者正如我们所说的那样,我们有一个库可以为您执行此操作,例如: http://htmlpurifier.org/

另一个可能的例子:

<?php    
   $javascript = '/<script[^>]*?javascript{1}[^>]*?>.*?<\/script>/si'; 
   $noscript = '';    
   $document = file_get_contents('test.html'); 
   echo preg_replace($javascript, $noscript, $document);  
?>

【讨论】:

    【解决方案3】:

    将您允许的标签和您允许的属性列入白名单,然后删除其他所有内容。您可以为此使用DOMDocument

    这段代码我写过一次,但从来没有其他人审查过它

    function legal_html($str, $tags='<a><b><br><i><span><table><tbody><tr><td><thead><th><img>', $attribArray=false) {
        if ($attribArray===false) {
            $attribs = array('id','class','src','href','alt');
        } else {
            $attribs = $attribArray;
        }
        $stripped = strip_tags($str,$tags);
        $dom = new DOMDocument();
        @$dom->loadHTML('<div>'.$stripped.'</div>');
        foreach ($dom->getElementsByTagName('*') as $node) {
            for ($i = $node->attributes->length -1; $i >= 0; $i--) {
                $attrib = $node->attributes->item($i);
                if (!in_array($attrib->name,$attribs)) $node->removeAttributeNode($attrib);
            }
        }
        $stripped = $dom->saveHTML();
        $start = strpos($stripped,'<div>')+5;
        $end = strrpos($stripped,'</div>');
        $stripped = trim(substr($stripped,$start,$end-$start));
        return $stripped;
    }
    

    【讨论】:

      【解决方案4】:

      你可以使用类似这样的东西-

      $content=$_POST['textbox'];
      
      if(strpos($content,'<script>')!==false){
      //show error;
      }
      else{
      //proceed with work;
      }
      

      【讨论】:

      • 虽然这是个好主意,但我希望其他文本仍然显示;并以某种方式将
      猜你喜欢
      • 1970-01-01
      • 2013-04-02
      • 2017-08-25
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      • 2017-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多