Javascript / jQuery DOM创建安全,直到它被添加到文档? [英] Is Javascript/jQuery DOM creation safe until it's added to the document?

查看:84
本文介绍了Javascript / jQuery DOM创建安全,直到它被添加到文档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请仔细阅读此声明:在将任何元素添加到文档 所有不安全元素$ dom已被删除。但是他们最初是创建的。好吧,让我们继续....






如果一段用户文本被处理,并且可能会加载如下: / p>

  var comment ='I'\\'ma naughty person !!'+ 
'< script src =http ://blah.com/some_naughty_javascript.js>';
var $ dom = $('< div>'+ comment +'< / div>');

这个本身是否有危险?我的观点是,只需简单地创建DOM就可以注入任何东西,或者只是简单的处理和创建结构?



例如:

  var $ dom = $('< script> alert(hi);< / script> ;'); 

显然,在添加到文档。但是:




  • 任何标签或以这种方式创建的任何内容都是危险的?

  • 在javascript / jquerywatch中,以这种方式创建的元素,并在它被剥离了坏元素并放在文档上之前执行?






赏金编辑



所以在下面的答案中概述,似乎这种方法不是很安全,特别是因为一个原因:




  • var $ dom = $('< img src =blah.jpg/                        b $ b

    这将为处理HTML ajax请求创建一个主要问题。例如,如果我们想从表单的输入中获取值:

      $。ajax({
    url :'test.php',
    success:function(responseHTML){
    var inputs = $(responseHTML).find('form input');
    }
    });

    这将不由自主地导致浏览器请求所有图像。



    赏金授予任何人




    • 谁能提供一个很好的,安全的

    • 理想地不提供正则表达式答案...即使我们想做 $(responseHTML) .find('img') - 使用正则表达式删除图像标签不能是一个选项,所以需要一个不显眼的方式来阻止src的加载,但仍然具有相同的属性,结构等等


    解决方案



    方式?我的观点是,可以只是
    简单的创建一个DOM的行为,不知何故
    注入任何东西,还是只是简单地
    处理,结构是
    创建?


    只需创建一个元素,而不将附加到dom将不会导致任何脚本运行,因为它完全是一个对象点(HtmlScriptElement)。当它实际上附加到dom时,脚本元素将被浏览器评估并运行。有人说,我认为这是一个非常狡猾的人可能会利用一些你可能在使用的框架或浏览器中出现的错误,导致不必要的结果。



    考虑这个例子:

     < p> 
    < input type =buttonvalue =存储脚本变量id =store/>
    < input type =buttonvalue =Append'脚本'To Domid =append/>
    < / p>
    < br />
    < p>
    < input type =buttonvalue =does nothing/>
    < / p>
    < h1>脚本< / h1>
    < pre id =script>
    $(function(){
    function clickIt(){
    $(this).clone()。click(clickIt).appendTo(body);
    }
    $(input [type ='button'])。val(Now Does Something)。click(clickIt);
    });
    < / pre>

    var theScript;

    $(#store)click(function(){
    theScript = document.createElement('script');
    var scriptText = document.createTextNode($ #script)。text());
    theScript.appendChild(scriptText);
    });

    $(#append)。click(function(){
    var head = document.getElementsByTagName('head')[0];
    head.appendChild );
    });

    当您点击 store 将会创建HtmlScriptElement并将其存储到变量中。您将注意到即使创建对象也没有任何运行。一旦您点击 append ,脚本就会被附加到dom并立即评估,按钮会有所不同。



    jsfiddle上的代码示例





    可以在javascript / jquery中的任何功能watch元素
    在这种方式下创建并执行
    ,之后它被剥离了不良的
    元素并放在文档上?


    jQuery sort 对于你已经是一样的内部脚本eval




    Karl Swedberg 发布在 .append()


    所有jQuery的插入方法都使用
    a内部的domManip函数
    clean / process元素之前和
    插入后DOM。
    domManip
    函数的一个事情是拉出任何脚本
    要插入的元素,并通过evalScript例程
    运行
    ,而不是注入他们与其余
    的DOM片段。它分别插入
    脚本,评估它们
    ,然后从DOM中删除它们。
    ...


    您可以更改jQuery的行为以删除所有< script / > ,并调用 append() onclick,mouseover等消除其他元素 c>然而,这只会影响jQuery,因为有人可以轻松地使用vanilla javascript附加< script /> 元素。



    Dom Mutation Events



    Dom Level 2 确定了一些Dom突变事件来捕获添加到dom中的元素,这些元素将会关注事件, DOMNodeInserted 。但是,在添加元素之后,它被触发。 ,根据Raynos,这些目前是已弃用


    DOMNodeInserted当节点
    被添加为另一个节点的子节点时触发。
    此事件在
    插入发生后发送。此事件的目标
    是插入
    的节点。气泡:是可取消:否
    上下文信息:relatedNode保存
    父节点


    没有完全停止通过一些其他javascript附加到dom的< script /> 。 (至少不是我能找到的)。



    我可以建议的最好的方法是永远不会相信用户输入,因为所有的用户输入都是邪恶的 即可。当你做dom操纵双重检查以确保没有禁止的标签,不管它是< script /> 或甚至是< p / > 元素,并在保留所有输入之前对其进行清理。



    此外,约翰指出,您需要担心可以附加 任何 元素> onclick 事件或任何内联JavaScript事件处理程序。


    Please read this statement carefully: let's assume before ANY elements are added to the document all unsafe elements in $dom have been removed. But they were initially created. Ok let's continue....


    If a piece of user text is processed and can possiblity be loaded like so:

    var comment = 'I\'m a naughty person!!' +
                  '<script src="http://blah.com/some_naughty_javascript.js">';
    var $dom = $('<div>' + comment + '</div>');
    

    Is this by itself dangerous in any way? My point being, can just the simple act of creating a DOM somehow inject anything, or is it just simply processed and the structure is created?

    For example:

    var $dom = $('<script>alert("hi");</script>');
    

    Obviously the message hi does not pop up until it's added to the document. But:

    • Can any tag or anything created in this manner be dangerous?
    • Can any functions in javascript/jquery "watch" for elements being created in this manner and act on it BEFORE it's been stripped of bad elements and put on document?

    Bounty Edit

    So as outlined in the answers below, it seems this method isn't very safe, particularly for one reason:

    • var $dom = $('<img src="blah.jpg"/>') -- this will request for the image straight away, regardless of if the object was added to the document.

    This creates a major problem for dealing with HTML ajax requests. For example if we wanted to get the values from the inputs of the form:

    $.ajax({
      url: 'test.php',
      success: function(responseHTML) {
        var inputs = $(responseHTML).find('form input');
      }
    });
    

    This will involuntarily cause all images to be requested for by the browser.

    Bounty is awarded to anyone:

    • Who can provide a nice, safe way of dealing with ajax requests without the above issue.
    • Ideally doesn't provide a regex answer... i.e. what if we wanted to do $(responseHTML).find('img') -- removing image tags with regex can't be an option, so an unobtrusive way would be needed to stop the src from loading, but still have the same attributes, structure, etc.

    解决方案

    Is this by itself dangerous in any way? My point being, can just the simple act of creating a DOM somehow inject anything, or is it just simply processed and the structure is created?

    Simply creating an element without appending it to the dom will not cause any script to run since it is purely an object at this point (HtmlScriptElement). When it is actually appended to the dom the script element will be evaluated and ran by the browser. With that being said I suppose it is possible that an extremely crafty person could exploit a bug that is present in some framework or browser you might be using to cause an undesired outcome.

    Consider this example:

    <p>
        <input type="button" value="Store 'The Script' In Variable" id="store"/>
        <input type="button" value="Append 'The Script' To Dom" id="append"/>
    </p>
    <br/>
    <p>
        <input type="button" value="Does nothing"/>
    </p>
    <h1>The Script</h1>
    <pre id="script">
        $(function(){
            function clickIt(){
                $(this).clone().click(clickIt).appendTo("body");
            }
            $("input[type='button']").val("Now Does Something").click(clickIt);
        });
    </pre>
    
    var theScript;
    
    $("#store").click(function() {
        theScript = document.createElement('script');
        var scriptText = document.createTextNode($("#script").text());
        theScript.appendChild(scriptText);
    });
    
    $("#append").click(function() {
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(theScript);
    });
    

    When you click on store it will create the HtmlScriptElement and store it into a variable. You will notice that nothing is ran even though the object is created. As soon as you click append the script is appended to the dom and immediately evaluated and the buttons do something different.

    Code Example on jsfiddle


    Can any functions in javascript/jquery "watch" for elements being created in this manner and act on it BEFORE it's been stripped of bad elements and put on document?

    jQuery sort of does that for you already as it does some internal script eval


    From Karl Swedberg post on .append()

    All of jQuery's insertion methods use a domManip function internally to clean/process elements before and after they are inserted into the DOM. One of the things the domManip function does is pull out any script elements about to be inserted and run them through an "evalScript routine" rather than inject them with the rest of the DOM fragment. It inserts the scripts separately, evaluates them, and then removes them from the DOM. ...

    You could alter the behavior of jQuery to remove all <script/> and sanitize other elements with inline javascript onclick, mouseover, etc when calling append() however that will only affect jQuery as someone could easily use vanilla javascript to append the <script/> element.

    Dom Mutation Events

    Dom Level 2 does defined some Dom mutation events to capture elements that are added to the dom one would look towards the event, DOMNodeInserted. However it is fired after the element has already been added. note, per Raynos these are currently deprecated.

    DOMNodeInserted Fired when a node has been added as a child of another node. This event is dispatched after the insertion has taken place. The target of this event is the node being inserted. Bubbles: Yes Cancelable: No Context Info: relatedNode holds the parent node

    In the end it appears there is no totally stop a <script/> being appended to the dom via some other javascript. (at least not that I can find).

    The best way I can suggest is to never ever trust user input as all user input is evil. When you do dom manipulation double check to make sure there are no forbidden tags, be it <script/> or even plain <p/> elements and sanitize all input before it is persisted.

    Also as John points out you need to worry about any element that can attach a onclick event or any inline javascript event handler.

    这篇关于Javascript / jQuery DOM创建安全,直到它被添加到文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆