Does anyone know if its possible to prevent a JavaScript function from accessing the DOM?
More info:
I am trying to create a "Threading" object for JavaScript, e.g. use the Worker object, fall back on setTimeOut when not available. Obviously the worker can't access the DOM, I would like to keep this standard.
Even more info:
One possible, but ugly possible solution (that I figured out just now):
function test(document, window)
{
}
But Nothing prevents the dev to access the dom from another function he calls within this function though - and you'll have to list the world of arguments.
No, that's not really possible in a normal browser environment.
You might be able to replace stuff like document.getElementById before calling the function and restoring it afterwards though... But I'm sure there are ways to get around this.
You could execute the function in a Web Worker. There is no access to DOM from a Web Worker.
But really, what are you trying to achieve?
Since your goal is to enforce conventions rather than to completely sandbox the JavaScript, you could indeed use a function with window, document and other DOM interfaces shadowed locally and then eval the third-party script:
(function test(window, self, top, document) {
'use strict';
eval(untrustedCode);
}());
Of course they still could access the real global object, but at least not directly.
Related
In the https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage page, it tell us that:
The CacheStorage interface represents the storage for Cache objects. It provides a master directory of all the named caches that a ServiceWorker, other type of worker or window scope can access (you don't have to use it with service workers, even though that is the spec that defines it) and maintains a mapping of string names to corresponding Cache objects.
so, i want to know.Is it better to use cacheStorage in ServiceWorker than in Window scope? why?
As nobody answer that, i want to share what i think.
In my opinion, there are several advantages.
First of all, serviceWorker is handled by another thread, which make it more efficient.
The next one, serviceWorker can simply add to old website without changing code, while you have to rewrite the ajax code etc, when you plan to use it in window scope.
The last but not least, you can run this when your page has been shut down.For example, you can put sth into cache when you got the push.
However, it still make me confused. Why the browser allow the window scope to get the permission.Is it a convenient way for us to just write in the main thread? Or, that will bring us some security risk, because when our page has been xss, that hacker can get access to cache?
Why the browser allow the window scope to get the permission?
Service Workers do not have access to DOM elements.
So if I want to precache some urls that are found on the current page it is much easier to do from the window scope than from the service worker.
Okay, so I've been trying to do userscripts for certain websites. However, all of the websites I want to do userscripts for have packing that does not expose anything to me.
For example, I want to write userscripts for this website but it doesn't expose enough to me for anything interesting.
Is there any possible way to get through a closure and into it's context? I know Chrome Dev Tools lets you view contexts, but not via code.
Remember, in this scenario, I cannot just simply add something to global context as I do not control the code.
Is there any possible way to get through a closure and into it's context?
If you mean, can you get to the foo here:
(function() {
function foo() {
}
// ...code using foo...
})();
No, you can't, if it's not explicitly made available outside that scoping function.
Web App Model
Suppose I have a sensitive JS object by which I can do critical stuff. My requirement is that I would like to wrap this object entirely such that no one can access it. Here is my pattern to wrap this object.
var proxy = (function (window){
// A private reference to my critical object (i.e. big apple)
var bigApple = window.bigApple;
// Delete this property so that no one else can access it
delete window.bigApple;
// Oooah, It's mine! I'm now eating it :)
// Public APIs exposed globally
return {
doStuffWithBigApple: function (){
// The Script element being executed now
var who = document.currentScript;
// Access control
if(isLegitimate(who)){
return bigApple.doStuff();
}
}
};
}) (window);
By this code I export a public literal object named proxy so that every one can access it.
What is that isLegitimate? It is an abstract function to be implemented which decides which script elements access to which methods of my big apple. The decision is made with regard to src attribute of the script element. (i.e. their domain)
Others use this public API like this:
proxy.doStuffWithBigApple();
Attack Model
In my web app there are placeholders for advertising such that external contents including JavaScript codes could be loaded and get executed. All of these external resources eagerly would want to access my big apple.
Note: Those are added after my scripts resulting in there is no access to the original window.bigApple.
My Question
Is there any circumventing way for my security model?
Critical edges:
Changing src attribute at parse-time. --- Not possible, because src can only be set once.
Adding script element at run-time --- No problem is raised
Your idea of creating a proxy is good imo, however, if you have access to ES6, why not looking into Proxy? I think it does what you want out-of-the-box.
The MDN provides good examples on how do traps for value validation in a setter, etc.
EDIT :
Possible trap I have imagined :
document.currentScript is not supported in IE. So if you care about it and decide to polyfill it/use a pre-exisiting polyfill, make sure it is secure. Or it could be used to modify on the fly the external script url returned by document.currentScript and skew the proxy. I don't know if this could happen in real life tho.
This way for protecting JavaScript objects has a very significant issue which should be addressed, otherwise this way will not work properly.
MDN noted on this API that:
It's important to note that this will not reference the <script> element if the code in the script is being called as a callback or event handler; it will only reference the element while it's initially being processed.
Thus, any call to proxy.doStuffWithBigApple(); inside callbacks and event handlers might lead to misbehaving of your framework.
I'm currently experimenting on self replicating code. Out of love for the language I'd like to write it in javascript.
I'm working on a program that writes a function's code which in turn writes its function own code and so on. Basically, the desired process is this:
I manually create A function which returns code (which includes some randomness) and a numeric value (proposed solution to a problem).
I call this function a number of times, evaluate the results of each of those returned functions, and continue the process until I have code that is sufficiently good for what I'm trying to do.
Now, I have always been told how eval is evil, how never to use it and so on. However for my specific use case it seems like the Function constructor or eval are exactly what I'm looking for.
So, in short the question is:
Are eval/Function constructor indeed the best tools to use in my case? If so, I figured I'd use the Function constructor to scope the code executed, but is there a way to truly limit it from accessing the global scope? Also, what are some good practices for eval usage in my case?
I think I just figured out something I could use:
If I run my javascript code using node.js I can use the vm module which allows me to execute javascript code safely in a new context, and without letting the executed code have any access to the local or global scopes.
vm.runInNewContext compiles code, then runs it in sandbox and returns the result.
Running code does not have access to local scope. The object sandbox will be used as
the global object for code. sandbox and filename are optional, filename is only used in
stack traces.
You can see a full example here: vm.runInNewContext
This will allow me to eval code safely, and seems to be the safest way (I found) currently available. I think this is a much better solution than eval or calling the Function constructor.
Thank you everyone who helped.
Unfortunately I believe there is no way to prevent it from accessing the global scope. Suppose for example that in a web browser i evaled some code like this :
(function(window) {
eval(script);
)(null));
Any time the script tries to access window - it will get an error, since window is null. However someone who knew what they were doing could always do this :
var global = (function() {
return this;
}());
Since when you invoke a function in what Crockford calls the "function invocation style" then the this is always bound to the global variable.
In Node.js, if I load a module which contains code in module-scope like:
this["foo"] = function() { console.log("foo"); }
...then I appear to get a globally available function that I can call just by saying foo() from any code using the module. It can be seen as one of the printed items with Object.getOwnPropertyNames(this).
However, if I put the following in module scope instead:
function foo() { console.log("foo"); }
...then it produces a function which can similarly be called within that module as foo(), but is invisible outside of it (e.g. does not show up as one of the items with Object.getOwnPropertyNames(this)).
I gather this is a change in runtime behavior from what's done in browsers. A browser seems to poke everything into global scope by default (and for years people have had to consciously avoid this by wrapping things up in anonymous functions/etc.)
My question is whether NodeJs has some secret way of interacting with these declarations outside of the module in which they are declared BESIDES using exports.(...) = (...). Can they be enumerated somehow, or are they garbage collected as soon as they are declared if they're not called by a module export? If I knew what the name of such a function was going to be in advance of loading a module...could I tell Node.js to "capture it" when it was defined?
I'm not expecting any such capabilities to be well-documented...but perhaps there's a debugger feature or other system call. One of the best pointers would be to the specific code in the Node.js project where this kind of declaration is handled, to see if there are any loopholes.
Note: In researching a little into V8 I saw that a "function definition" doesn't get added to the context. It's put into an "activation object" of the "execution context", and cannot be programmatically accessed. If you want some "light reading" I found:
http://coachwei.sys-con.com/node/676031/mobile
http://perfectionkills.com/understanding-delete/
if you fill in exports.foo = foo; at the end of your file it will be available in other files in node, assuming that you do var myFile = require('myFile.js') with the file name and you call the function via myFile.foo(); You can even rename the function for outside use in exports and set whatever you want to call the package when you use require.
BTW you can enumerate these functions just like you do on any JSON object (ie for k in ...)
This is impossible in node without more advanced reflection tools like the debugger.
The only way to do this would be to use __parent__ which was removed due to security issues and other things (hard to optimize, not standard to begin with) . When you run the script those variables become closed under the module. You can not access them elsewhere without explicitly exporting them.
This is not a bug, it's by design. It's just how node works. see this closely related question.
If this sort of reflection was available without tools like the debugger it would have been extremely hard to optimize the source code (at least the way v8 works) , meaning the answer to your question is no. Sorry.