..."The summary being - you can't allow anyone else reference to either your element OR your callback function. But HOW??"
That's the question, isn't it: How do you create a script element, add it to the page, make it load an external script, without ANYONE being able to get reference to it?
That's the question, isn't it: How do you create a script element, add it to the page, make it load an external script, without ANYONE being able to get reference to it?
Think about it this way - how does anyone on the page get reference to anything else?
Answer: calls, global scope, or DOM.
Internally scoping blocks the 2nd option. So DOM and function call remain. Your code certainly isn't making any calls, but the page is - all the time - through events. So this list becomes: "Events and DOM reference". DOM reference can be blocked simply by removing your script element from the DOM - the only way to guarantee no one gets reference to it directly is by removing the element (from the DOM) before the script that attached the element (to the DOM) is finished running. Obviously this is not enough time for the script to actually load - and every browser handles what happens next differently. Grrrrr.
Firefox just runs the script no matter what. Yay Firefox! Or boo?? Maybe I should be concerned that I can do this...?
Suppressing the appropriate events on all three major browsers, and for all their (sometimes crappy) versions was a ROYAL PAIN in my rear. But I managed it. With a few caveats.
See my next post for those details...
So.
Since I can block* reference to the element, no one can add listeners, therefore no one can fake/counterfeit my loading of the external resource. But there still has to be a pipeline between the loaded resource and the loader. The loaded JS will run on the page scope, nothing I can do about that, so I have to find a way for it to run, then load it into my own private scope, and remove the traces of it on the global scope, before anyone else can do anything about it. One way would be to pass a "key" from within the private scope, to the loaded JS, which then uses that "key" to set a global object which can only be referenced using that "key". A very helpful fact is that the event listeners on the element are guaranteed to run immediately after the loaded script runs (the onload attribute being first, the eventListeners second, and in order. yes, they actually run in order in my tests). Given that fact, I don't actually need a private key, I just need an agreed upon reference that will be on the global scope.
At this point we just have two scripts, one running right after the other. Guaranteed. So it becomes a simple thing to pass information from the first to the second, and then remove the traces of the first one. The second script is in a private scope, so BOOM, we have secure loading.
No entity on the page can possibly even know anything just happened.
As I said, see my next post for some details
No comments:
Post a Comment