How do I safely “eval” user code in a webpage?

后端 未结 5 783
难免孤独
难免孤独 2020-12-16 01:19

I\'m working on a webapp to teach programming concepts. Webpages have some text about a programming concept, then let the user type in javascript code into a text editor wi

相关标签:
5条回答
  • 2020-12-16 01:52

    So from what I can tell if you are eval'ing a user's input only for them, this isn't a security problem. Only if their input is eval'd for other users you have a problem.

    Eval'ing a user's input is no worse than them viewing source, looking at HTTP headers, using Firebug to inspect JavaScript objects, etc. They already have access to everything.

    That being said if you do need to secure their code, check out Google Caja http://code.google.com/p/google-caja/

    0 讨论(0)
  • 2020-12-16 01:57

    Not clear if the eval() occurs on client or server side. For client side:

    • I think it's possible to eval safely in an well configured iframe (https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/)

    • This should be 100% safe, but needs a couple of libraries and has some limitations (no es6 support): https://github.com/NeilFraser/JS-Interpreter

    • There are lighter alternatives but not 100% safe like https://github.com/commenthol/safer-eval.

    • Alternatively, I think something similar can be implemented manually wrapping code in a with statement, overriding this, globals and arguments. Although it will never be 100% safe maybe is viable in your case.

    0 讨论(0)
  • 2020-12-16 02:04

    Your biggest issue will always be preventing infinite loops for occurring in user-provided code. You may be able to hide "private" references by running eval in the right context, e.g.:

    let userInput = getUserInput();
    setTimeout(() => {
      let window = null;
      let global = null;
      let this = null;
      // ... set any additional references to `null`
      
      eval(userInput);
    }, 0);
    

    And you could wrap the above code in a try/catch to prevent syntax and logic errors from crashing outside of the controlled eval scope, but you will (provably) never be able to detect whether incoming user input defines an infinite loop that will tie up javascript's single thread, rendering its runtime context completely stalled. The only solution to a problem like this is to define your own javascript interpreter, use it to process the user's input, and provide a mechanism to limit the number of steps your javascript interpreter is willing to take. That would be a lot of trouble!

    0 讨论(0)
  • 2020-12-16 02:08

    This is a trick question. There is no secure way to eval() user's code on your website.

    0 讨论(0)
  • 2020-12-16 02:09

    It can't be done. Browsers offer no API to web pages to restrict what sort of code can be executed within a given context.

    However, that might not matter. If you don't use any cookies whatsoever on your website, then executing arbitrary Javascript may not be a problem. After all, if there is no concept of authentication, then there's no problem with forging requests. Additionally, if you can confirm that the user meant to execute the script he/she sent, then you should also be protected from attackers, e.g., if you will only run script typed onto the page and never script submitted via GET or POST data, or if you include some kind of unique token with those requests to confirm that the request originated with your website.

    Still, the answer to the core question is that it pretty much is that it can't be done, and that user input can never be trusted. Sorry :/

    0 讨论(0)
提交回复
热议问题