Is external JavaScript source available to scripting context inside HTML page? - javascript

When an external JavaScript file is referenced,
<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
is the JavaScript source (lines of code before interpretation) available from the DOM or window context in the current HTML page? I mean by using only standard JavaScript without any installed components or tools.
I know tools like Firebug trace into external source but it's installed on the platform and likely has special ability outside the context of the browser sandbox.

Nope. There's no Javascript API for loading the true content of <script> tags. This is actually not an oversight, but rather a security feature: suppose I request the .json file that Gmail requests via AJAX to load your inbox by putting it in an external <script> tag. A JSON document is valid Javascript (granted, without side-effects), so it would run without error. Then, if I could inspect the content of the external script, I would be able to read your e-mail. (I'm almost certain that Gmail is more complex than that, but most sites are not.)
So, making up a few things about how Gmail works, here's how the attack would look:
<script id="inbox" type="text/javascript" src="http://mail.google.com/OMGYOURINBOX.json"></script>
<script type="text/javascript">
// Supposing a value called `externalScriptContent` existed on a script tag:
var inboxJSON = document.getElementById('inbox').externalScriptContent;
var messages = JSON.parse(inboxJSON);
for(var i in messages) {
// Do something malicious with each e-mail message
alert(messages[i].body);
}
</script>
If a script tag had the value externalScriptContent, I could just put whatever URL in for the src that I wanted, and then summon up the remote file's contents, effectively circumventing AJAX cross-origin restrictions. That'd be bad. We allow cross-origin requests for remote scripts because they are run and run only. They cannot be read.
Firebug has these permissions because Firefox extensions have the ability to inspect anything that the browser requests; normal pages, thankfully, do not.
However! Bear in mind that, if the script is on your domain, instead of writing it in <script src="…"></script> form, you can pull it up with an AJAX request then eval it to have access to the contents and still only request it once :)

You can parse the <script> tag and re-request the js file by XMLHttpRequest, it will likely be readily served from cache and with credentials of the current page. But unless both your requesting script and the script in the tag originate from the same domain, the browser will disallow this.

Related

Phantomjs: Modifying html dom before opening it as webpage

I need to process html files that have corrupted script files that are added to it via tag.
Im planning to remove all script tag present in the webpage via phantomjs.
But on opening the webpage via webpage.open(), phantomjs parse error is thrown since it cannot parse the JS content within the script tag.
Here is an example:
<html>
<head>
<script>
corrupted JS
if(dadadd
;
</script>
<body>
some content
</body>
</html>
Can someone help me on suggesting the right way to clean this webpage using phantomjs ?
It's not (easily) possible. You could download (not through opening the page, but rather making an Ajax request in page.evaluate()) the static html, then change according to your needs, then assign it to page.content.
This still might not work, because as soon as you assign it to page.content, you're saying that PhantomJS should interpret this source as a page from an unknown domain (about:blank). Since the page source contains all kinds of links/scripts/stylesheets without a domain name, you'll have to change those too in order for the page to successfully load all kinds of resources.
It might be easier to just have a proxy between PhantomJS and the internet with a custom rule to adjust the page source to your needs.

Loading a script file in a Chrome App Sandbox

I'm working on a Chrome App, and I have a script file that's saved in the app's sandboxed filesystem. (It's available via a URL filesystem:chrome-extension_****/Persistent/script.js
I'm able to use Chrome's FileSystemAPI to read the file in the main app window. However, I need it to be accessible and executable in a sandboxed page.
I have the following in my manifest -
"sandbox": {
"pages": ["sandboxed_page.html"],
"content_security_policy": "sandbox allow-scripts;"
},
And I'm using the page like this:
<iframe id="sandbox_frame" seamless="seamless" src="sandboxed_page.html" sandbox="allow-scripts"></iframe>
I tried loading the file in the main app window, use window.URL.createObjectURL() to convert it to a blob: URL, and passed this URL via postMessage() to the sandbox. In the sandbox, I'm trying to load the URL into a <script> element. I get an error saying Not allowed to load local resource: blob:chrome-extension%3A//...
The other option (which is working) is load the contents of script.js in the main app, and send the entire string through postMessage(). Not sure this is a good idea, as script.js could get pretty big.
Am I doing something wrong, or is loading local scripts in sandboxes prohibited by Chrome's security policies?
I went through https://developer.chrome.com/apps/app_external, but there's no mention of sending the external resources to the sandbox.
Sandboxed pages execute in a unique origin i.e. one that is different from the App itself, and you can't access filesystem URLs across different origins. The same goes for object URLs created from those files.
You're basically stuck with the postMessage approach, though you may be able to make it more efficient by transfering it as an ArrayBuffer rather than copying the data as a string. See https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers#Passing_data_by_transferring_ownership_(transferable_objects).

How can I recover my page from not being able to load a javascript file?

In a page that I work with, we load content from an external server from a provided dynamically created javascript file.
In one of the sections of the document that displays header content, we have the sample line:
<script type="text/javascript" src="externalScriptLocation"></script>
The problem is that when the external script location is down (it could be a 404, but in this case it's actually a 503 - service not available), most of the page's functionality appears to work but the page is not able to properly submit data.
Is there a way I can wrap this with a try/catch or something similar so that failure to load this bit of javascript (which is for a header element that, while it should be there, shouldn't cause these issues!) so that the site can function normally?
If it matters, the server side language is Java with Java Server Pages as the view.

Javascript detect which host it was loaded from

I have a Javascript library I'm working on. It can be self-hosted or run from another server. The script makes a number of AJAX calls and the preferred method is making POST requests to the same host as the including page. To allow for cross-domain calls it also supports JSONP, but this limits the amount of data that can be sent (~2K to safely accommodate most modern browsers' URL length limits).
Obviously the user including the script knows where they're getting it from and could manually select JSONP as needed, but in the interest of simplifying things, I'd like to detect, within the script itself, whether the script was loaded from the same host as the page including it or not.
I'm able to grab the script element with jQuery but doing a $('script').attr('src') is only returning a relative path (e.g. "/js/my-script.js" not "http://hostname.com/js/my-script.js") even when it's being loaded from a different host.
Is this possible and if so, how would I go about it?
Thanks in advance.
Don't use JSONP, use CORS headers.
But if you really want to do JS check, use var t = $('script')[0].outerHTML.
Effect on my page:
[20:43:34.865] "<script src="http://www.google-analytics.com/ga.js" async="" type="text/javascript"></script>"
Checking location.host should do the trick.

Is it possible to get the text of a script that is loaded from a source as opposed to in line code?

Currently I'm just taking source of a script that is on the page.
The HTML:
<script type="text/plain">meow</script>
The JavaScript:
// returns "meow"
document.querySelector('script').text
I want to be able to load the script from another file.
The HTML:
<script type="text/plain" src="file.txt"></script>
file.txt:
meow
The JavaScript:
// returns "meow"
document.querySelector('script').textFromFile
Does anyone know if that's possible? I would assume it's not, and I haven't found anything on google that is what I'm asking.
If the script has a src attribute you would need to fire of a request via XHR to that same path and pull in the text content of its response. Keep in mind this will require additional work if the script is being loaded from another domain. At that point you would need to make use of CORS, or introduce some other type of proxy to handle the cross-domain communication.

Categories