Is it possible to detect external scripts that might be loaded into a page by browser add-ons, a proxy, xss, etc?
Say I have this web page:
<html>
<head>
<title>Hello world!</title>
<script src=".js"></script>
</head>
<body>
Hello world!
</body>
</html>
Would it be possible to include some script in my script.js
file that would detect when other script elements on the page do not originate from ?
I want something that could detect other scripts somehow included in the source (i.e. they are present when the onload event fires) and scripts added any time after page load.
If I can detect those scripts, can I also stop them somehow?
This would be useful in debugging javascript/ui issues reported by users if I knew there was other stuff going on.
I use jQuery, so a jQuery answer will work for me. I just didn't want to limit answers to jQuery only.
EDIT
My solution is below. However, there are two (potential) problems with it:
- It depends on jQuery.
- It will not detect foreign resources loaded via CSS @import rules (or any rule with a
url()
value).
If someone would like to submit an answer that solves one or both of those issues, I will upvote it.
If you solve both, I will accept your answer.
Is it possible to detect external scripts that might be loaded into a page by browser add-ons, a proxy, xss, etc?
Say I have this web page:
<html>
<head>
<title>Hello world!</title>
<script src="http://mydomain./script.js"></script>
</head>
<body>
Hello world!
</body>
</html>
Would it be possible to include some script in my script.js
file that would detect when other script elements on the page do not originate from http://mydomain.
?
I want something that could detect other scripts somehow included in the source (i.e. they are present when the onload event fires) and scripts added any time after page load.
If I can detect those scripts, can I also stop them somehow?
This would be useful in debugging javascript/ui issues reported by users if I knew there was other stuff going on.
I use jQuery, so a jQuery answer will work for me. I just didn't want to limit answers to jQuery only.
EDIT
My solution is below. However, there are two (potential) problems with it:
- It depends on jQuery.
- It will not detect foreign resources loaded via CSS @import rules (or any rule with a
url()
value).
If someone would like to submit an answer that solves one or both of those issues, I will upvote it.
If you solve both, I will accept your answer.
Share Improve this question edited May 23, 2017 at 11:45 CommunityBot 11 silver badge asked Apr 18, 2012 at 21:15 Andrew EnsleyAndrew Ensley 11.7k16 gold badges64 silver badges73 bronze badges4 Answers
Reset to default 3You could check all script elements on domready like this:
$(function () {
$('script').each(function () {
check script source here
})
})
but, if someone could inject script tags in your side, he can also delete your code before you can start the check, also it will be hard to delete objects and functions the script could create before your recognize it.
So I dont think its a good solution to start investing time in this field. Its much more important to be clear that you cant trust the client anyway.
As you wanna figure out it anyway there are a bunch of DOM events to check if the DOM tree has changed.
I wasn't satisfied with the answers I received (though I appreciate Andreas Köberle's advice), so I decided to tackle this myself.
I wrote a function that could be run on demand and identify any html elements with foreign sources. This way, I can run this whenever reporting a javascript error to get more information about the environment.
Code
Depends on jQuery (sorry, element selection was just so much easier) and parseUri()
(copied at the bottom of this answer)
/**
* 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;
}
Usage
var s = getExternalSources('mydomain.');
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();
The search is inclusive of subdomains, so elements with sources of www.mydomain.
or img.mydomain.
would be allowed in the above example.
Note that this will not pick up on foreign sources in CSS @import
rules (or any CSS rule with a url()
for that matter). If anyone would like to contribute code that can do that, I will upvote and accept your answer.
Below is the code for parseUri()
, which I obtained from https://gist.github./1847816 (and slightly modified).
(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);
You could listen for changes in DOM and see if a new script tag is being inserted. But may I ask, what is the reason for such a need? I doubt you will be able to detect all possible cases where some arbitrary JS is executed against your page's DOM (e.g. a bookmarklet, or greasemonkey script).
I think the same origin policy may cover this: http://en.wikipedia/wiki/Same_origin_policy