1

Is it possible for two scripts included via script tag on the same page to keep secrets from one another?

For example, if one script contains

(function (myArg) {

    //do stuff with secret string

}('secretstring'));

is there any avenue for another script included on the page to determine 'secretstring'?

Spain Train
  • 5,890
  • 2
  • 23
  • 29
  • Well, you're passing 'secretstring' from an outer scope. If that's a variable, anything with access to the outer scope can see it. Other than that, no. – bfavaretto Jul 30 '13 at 18:39
  • In this case, `'secretstring'` cannot be seen by anything except for the anonymous function you're passing it to. – Andrew Larsson Jul 30 '13 at 18:43
  • you can iterate the script tag and find the .src of the file and examine it's contents statically. if you serve the js from off-site without cors, and it can't emit errors no matter what environment it runs in, then it's safe. – dandavis Jul 30 '13 at 18:50
  • Oh, you're asking for a hack that lets you see `'secretstring'` from another script on the page. I see. – Andrew Larsson Jul 30 '13 at 18:58
  • Good answers. For clarification assume: 1.) 'secretstring' is dynamic and specific to the user and session, and 2.) we are trying to keep the secret form the origin rather than the user. So origin includes our script file and we want 'secretstring' to be accessible only to our code and the user. – Spain Train Jul 31 '13 at 20:15

3 Answers3

2

You can run this jQuery code:

$('script').each(function() {
    alert(this.src); // $(this).html() or .text() will show any inline script content
});

And it will show the URL that can be used to load the content of any script.

That loaded content will contain the 'secretString' as well as all the javascript.

That's a lot of work to go to for a script to get something. But if you allow loading a script over a network, it can't really be secret.

Another way for a person (but not a script) to see it is if the browser or machine has a proxy running, all the content loaded can be seen. This can be done in various browsers by using the built-in or installable debugger.

Lee Meador
  • 12,829
  • 2
  • 36
  • 42
  • 1
    You could have a one-time-use token that's passed to the server when retrieving the source. That way, `'secretstring'` is only shown to the first requester with the correct token. That doesn't protect from `.src`, though. – Andrew Larsson Jul 30 '13 at 18:56
  • @AndrewLarsson That's a very good idea and clearly explained. Thank you. It does cut down the ways to view it. The script could be visible but load the secret with a one-time use token, as well. – Lee Meador Jul 30 '13 at 18:59
  • Is there another way to load the script such that the source is readable even when XHR and X-Frame-Options are denied? – Spain Train Jul 31 '13 at 20:13
1

Depends.

From program logic point of view, variables inside closures are inaccessible from outside, unless explicitly exported.

From a security point of view, one can't access variable values, but may still access a function's definition through toString. If a function, is not linked to a global variable (including dom), and it's coming from an external file, and is not embedded in the document (in which case one might use innerHTML), and it's not on the same domain as the page (in which case it would be possible to load the file in an iframe, and read it's source)... then as far as I know there is no way to access it's source.

It's also possible to override many built-in javascript functions. So the following scenario still exists (unless your code runs before any untrusted code, and never runs again):

<script>
function grab(arg) {
  // do something evil.
}
console.log = grab;
</script>

<script>
(function(myArg) {
  console.log(myArg);
}('secret'));
</script>
sabof
  • 8,062
  • 4
  • 28
  • 52
0

Secret is not the correct word. This is called a self invoking anonymous function.

(function () {
    // all my code+all my variables
    var a="some value";
    // a can be used anywhere inside this
    // b is unreachable here (it's undefined and hasn't even been instantiated in its own scope yet, as the anonymous function below gets invoked after this one has finished executing)
}());
// a is unreachable here (it's undefined)

(function () {
    // all my code+all my variables
    var b="some value";
    // b can be used anywhere inside this
    // a is unreachable here (it's undefined)
}());
// b is unreachable here (it's undefined)

IIFE aka self invoking anonymous functions are useful for isolating the scope.

IIFE are executed immediately as they are encountered in JavaScript.

So, a and b have different scopes and cant be used in each others' scopes.

What is the (function() { } )() construct in JavaScript?

http://benalman.com/news/2010/11/immediately-invoked-function-expression/

Community
  • 1
  • 1
HIRA THAKUR
  • 17,189
  • 14
  • 56
  • 87