If you're trying to make a function that can't be found by code loaded later in the page for security reasons, you should know that properties are of window are enumerable by default, and JavaScript's PRNG is not crypto-strong.
@MikeSamuel that's exactly what I'm trying to do.
If you had a crypto-strong source of randomness then you can use a lock&key approach to make a function that can only be called by someone who knows the secret.
For example,
(function () {
// Multiple calls to a secure source of randomness could get you more entropy than 64B.
var key = Math.random() + '/' + Math.random() + '/' + Math.random();
var sensitiveFunction = function () { alert("Don't leak me"); }
var slice = [].slice;
function lock(f) {
var g = f;
f = null; // arguments is widgy and leaky in non-strict mode.
return function (unlocker, var_args) {
if (key !== unlocker) { throw new Error(); }
return g.call(this, slice.apply(arguments, 1));
};
}
myGlobal = lock(sensitiveFunction);
})();
which uses the secret to wrap a function in one whose toString()
does not return sensitive code, and which will only be callable by code that can read var key
.
Is Math.random() cryptographically secure? discusses some alternatives to Math.random
for strong nonces in JavaScript but I don't have personal experience with any of them.
This isn't practically useful unless you can get key
out of this closure to code that needs it, so you need to have a secure communication channel to that code. You probably also want to have any script that defines this go through <script>
elements and delete their text content from the DOM so that the body of the sensitive function can't be read that way.
I believe some frameworks like waterken use the URL fragment to seed web applications with secrets and then use techniques like this within the page to keep them from prying code.
Note that making properties with unpredictable names un-enumerable does not protect them.
In EcmaScript 5, getOwnPropertyNames
does not respect enumerability. The only standardized way to get truly un-enumerable properties is with weak maps and a closely held object token and that will have to wait for EcmaScript 6 to be in an actual spec though browser vendors are implementing a lot of ES6 speculatively.