Javascript:检测/防止外部脚本

时间:2012-04-18 21:15:15

标签: javascript html load xss external

是否可以检测可能通过浏览器加载项,代理,xss等加载到页面中的外部脚本?

说我有这个网页:

<html>
    <head>
        <title>Hello world!</title>
        <script src="http://mydomain.com/script.js"></script>
    </head>
    <body>
        Hello world!
    </body>
</html>

是否可以在我的script.js文件中包含一些脚本,以检测页面上的其他脚本元素 来自http://mydomain.com

我想要的东西能够以某种方式检测其他脚本包含在源中(即,当onload事件触发时它们存在)并且在页面加载之后随时添加脚本

如果我能检测到这些脚本,我还能以某种方式阻止它们吗?

如果我知道还有其他事情发生,这对于调试用户报告的javascript / ui问题很有用。

我使用jQuery,所以jQuery的答案对我有用。我只是不想限制jQuery的答案。


修改

My solution如下。但是,它有两个(潜在的)问题:

  1. 这取决于jQuery。
  2. 它不会检测通过CSS @import规则(或任何url()值的规则)加载的外部资源。
  3. 如果有人愿意提交一份解决其中一个或两个问题的答案,我会对其进行投票。

    如果您同时解决这两个问题,我会接受您的回答。

4 个答案:

答案 0 :(得分:3)

您可以像这样检查所有脚本元素:

$(function () {
    $('script').each(function () {
        check script source here
    })
})

但是,如果有人可以在你身边注入脚本标签,他也可以在你开始检查之前删除你的代码,也很难删除脚本在识别之前创建的对象和功能。

所以我认为这不是一个很好的解决方案,可以开始在这个领域投入时间。更重要的是要明确你无论如何都不能信任客户。

正如你想弄清楚的那样,有一堆DOM events来检查DOM树是否已经改变。

答案 1 :(得分:1)

我对收到的答案不满意(虽然我很欣赏Andreas Köberle's advice),所以我决定自己解决这个问题。

我编写了一个可以按需运行的函数,并使用外部源识别任何html元素。这样,每当报告javascript错误时我都可以运行它来获取有关环境的更多信息。

代码

取决于jQuery(抱歉,元素选择更加简单)和parseUri()(复制在此答案的底部)

/**
 * Identifies elements with `src` or `href` attributes with a URI pointing to
 * a hostname other than the given hostname. Defaults to the current hostname.
 * Excludes <a> links.
 * 
 * @param string myHostname The hostname of allowed resources.
 * @return array An array of `ELEMENT: src` strings for external resources.
 */
function getExternalSources(myHostname)
{
    var s, r = new Array();
    if(typeof myHostname == 'undefined')
    {
        myHostname = location.hostname;
    }
    $('[src], [href]:not(a)').each(function(){
        s = (typeof this.src == 'undefined' ? this.href : this.src);
        if(parseUri(s).hostname.search(myHostname) == -1)
        {
            r.push(this.tagName.toUpperCase() + ': ' + s);
        }
    });
    return r;
}

用法

var s = getExternalSources('mydomain.com');
for(var i = 0; i < s.length; i++)
{
    console.log(s[i]);
}

// Can also do the following, defaults to hostname of the window:
var s = getExternalSources();

搜索包含子域名,因此上述示例中允许包含www.mydomain.comimg.mydomain.com来源的元素。

请注意,这不会在CSS @import规则(或任何带有url()的CSS规则)中获取外来源。如果有人愿意提供可以做到这一点的代码,我会投票并接受你的回答。


以下是parseUri()的代码,我是从https://gist.github.com/1847816获得的(稍加修改)。

(function(w, d){
    var a,
        k = 'protocol hostname host pathname port search hash href'.split(' ');
    w.parseUri = function(url){
        a || (a = d.createElement('a'));
        a.href = url;
        for (var r = {}, i = 0; i<8; i++)
        {
            r[k[i]] = a[k[i]];
        }
        r.toString = function(){return a.href;};
        r.requestUri = r.pathname + r.search;
        return r;
    };
})(window, document);

答案 2 :(得分:0)

您可以侦听DOM中的更改,并查看是否插入了新的脚本标记。但请问,这种需求的原因是什么?我怀疑你能够检测到所有可能的情况,其中对你的页面的DOM执行一些任意的JS(例如bookmarklet或者greasemonkey脚本)。

答案 3 :(得分:0)

我认为相同的原产地政策可能涵盖这个: http://en.wikipedia.org/wiki/Same_origin_policy