How to safely run user-supplied Javascript code inside the browser?

前端 未结 3 1077
执笔经年
执笔经年 2021-02-02 00:22

Imagine a scenario where I want to continuously invoke user-supplied Javascript code, like in the following example, where getUserResult is a function that some use

3条回答
  •  伪装坚强ぢ
    2021-02-02 00:37

    You can do this with workers. The best thing about workers is that they run in a different process, so if that user code gets into an infinity loop will not hang your page. The only interface with the worker is a message interface, so strings only are exchanged which is extremely secure but limited in some situations.

    As not all currently used browsers support workers, iframes are a helpful alternative. You can create them in javascript, set display to 'none', add them to the document, get the eval function from the iframe contentWindow, then 'destroy' the iframe, like setting the outerHTML to '' (empty string). It is tricky, as sometimes the iframe window get garbage collected, but if you manage to do it right, you will have an eval that has a different global object bound to it, which has an empty document. You can then create an interface with the code running it that global with the code running in your page global. The security depends on how do you implement that interface. You should not expose your global object, that means you should nullify the 'parent' property in the iframe global before running any user code there. You should also make sure you don't pass any Element object from the page document to the code running in the iframe global, or the user running that code will be able to navigate your whole document through the parentElement property, you should wrap them to your Element interface using Object.defineProperty for example. It is a lot of work, it did it once, but it is not sure that will be compatible between browsers. For example, if I well remember and I am not making a mistake, Chrome let me nullify the parent property in the iframe global, while in Safari on an iPad I wasn't able. Sorry I don't have any code to share with you right now, I will post it if I have time. However, iframes scripts run in the same process than the page, which it means that an infinite loop will hang your page scripts at well, and today browser compiling the code to machine instructions can effectively hang the client os (depending of the browser and the os).

    Third you can use a sandbox, there are JavaScript self interpreters or like in T.J. Crowder comment compilers that will simplify that for you, but the side effect is that it will run slower, specially interpreters.

    IMHO, I think the folks at ECMA should better worry less about ugly arrow syntax and stuff like that and implement a secure way of running process with different global that have an interface an specific document element and its descendants but unable to get that element parent and access to the document. This will effectively enable a way of writing JavaScript plugins and also secure advertisement system.

提交回复
热议问题