Defensive Javascript - Run code safely on untrusted pages
defensivejs.com
defensivejs.com
E = (function() {
var F = function(x) {
var secret = 42, key = 0xC0C0ACAFE;
return x===key ? secret :0
};
return function G_F(x) { return F(x>>>0) }
})();
The neat thing about this is that at runtime you can't get to the secret. I initially thought you might be able to toString the function but that won't work because it will only show you the algorithm used e.g. function G_F(x) { return F(x>>>0) }
Still, I was thinking if you could devise a plan to remotely fetch the source then you could, I believe defeat all of this extra security... unless of course the server can secure things such that the key is unique to each request...It may be pure hazard, but in the following two calls,
E(0x000000FE);
E(0xC0000000);
The second one is significantly slower: http://jsperf.com/qsmflkjtestOne solution is to use a string comparison. The high number is only 7% slower in that case.
A: We only focus on semantic language safety, and if you use the translation to ProVerif, the correctness of the protocol implementation. There are many side channels available to a same-origin attacker - the most obvious ones being time and memory. In SJCL, we sometimes try to mitigate those channels - for instance, in CCM tag validation. However, we do not have any formal proof of robustness against any side-channel attacker - furthermore, user-written DJS code must also take into account this risk. For instance, use the AES.ctEq function for constant time string comparison.
E = (function() {
var F = function(x) {
var secret = 42, key = 0xC0C0ACAFE;
return x===key ? secret :0
};
return function G_F(x) {
console.log(document.getElementById("test").innerHTML.split("secret")[1].substr(3,2)); return F(x>>>0);
}
})();
E();
</script>The above is very hacked together... does this break the security? Or am I misreading this?
A = E; E = function(x){ window.secret=A(x); return window.secret };
As you can just change how the function works.
On the script server page you are outlining a method to assure that your defensive scripts are only sent to verified requesters. Presumably, this is to ensure that scripts are only loaded into the browser, and only on pages that are intended by the script author. If those goals can be met, any secure data can be encapsulated - effectively securing it from any other malicious JS that might be running on the page.
I don't see how such a goal could possibly be completed.
Your defensive server code uses the following method to confirm the origin:
// Browser origin does not match claimed origin if(getenv('HTTP_ORIGIN') != $org['origin'] || strlen($c = $_POST['challenge']) != 64) { die(header("HTTP/1.1 403 Access denied")); }
It is relying on the HTTP_ORIGIN header to confirm that the request is coming from the correct origin. However, like any other HTTP Header, the HTTP_ORIGIN header can be spoofed. Presumably, some malicious javascript could keep an eye out for any scripts called from the defensive server. It could then call home (JSONP?) to a server that spoofs HTTP_ORIGIN, and get a stripped down version of the scripts. The malicious JS would now have access to your secret data.
Even all of that is likely over complex. What is stopping the malicious JS from loading the defensive scripts via XHR, stripping out the encapsulation, and then eval()ing it?
Again, there's parts of this system that I don't understand, and probably some large mistakes in my logic here. I'd just like to have someone smarter than me point them out :)
Caja lets you safely run untrusted code in your app.
Defensive JavaScript lets you run your code which contains secrets in an untrusted app (assuming you're able to load the code without the app seeing it somehow)