6

是否可以检测到可能被浏览器加载项、代理、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。


编辑

我的解决方案如下。但是,它有两个(潜在的)问题:

  1. 它依赖于 jQuery。
  2. 它不会检测通过 CSS @import 规则(或任何具有url()值的规则)加载的外部资源。

如果有人想提交解决其中一个或两个问题的答案,我会投赞成票。

如果你两个都解决了,我会接受你的回答。

4

4 回答 4

3

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

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

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

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

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

于 2012-04-18T21:30:11.033 回答
1

我对收到的答案并不满意(尽管我很欣赏Andreas Köberle 的建议),所以我决定自己解决这个问题。

我编写了一个可以按需运行的函数,它可以识别任何具有外国来源的 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.comor来源的元素。img.mydomain.com

请注意,这不会在 CSS@import规则(或任何带有 aurl()的 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);
于 2012-05-04T17:20:17.290 回答
0

您可以侦听 DOM 中的更改并查看是否正在插入新的脚本标签。但我可以问,这种需要的原因是什么?我怀疑您是否能够检测到针对您页面的 DOM 执行某些任意 JS 的所有可能情况(例如,小书签或油脂猴脚本)。

于 2012-04-18T21:21:16.327 回答
0

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

于 2012-04-18T21:30:06.960 回答