4 ms·
Okay, I'll bite. I have known for a long time that eval is evil. Then, last year I actually needed to evaluate a string (from a file). As the case was safe enou
by beefield 5y ago
Okay, I'll bite. I have known for a long time that eval is evil. Then, last year I actually needed to evaluate a string (from a file). As the case was safe enough (input 100% controlled by me), I did not worry too much and just used eval. But what would be a safe way to evaluate things if you needed to do that in unsafe environment? Say, you would like to make a safe website that allows user type a python code snippet and that would be evaluated/executed server side? Is that even possible?
- lemoncucumber 5y agoSure, that's basically what services like AWS Lambda do. As a starting point, you'd want to run the code in a short-lived VM with little to no network access which is dedicated to just running untrusted code.
- nl 5y agoThis is a bad solution. Lambda allows arbitraty network access and may allow access to your AWS resources. If you have to do this, the best approach is to containerise it, use capabilities to enforce restrictions and run in a virtual machine as isolated as possible. It's still not great though. Some languages (eg Java) have additional features that help with this though.
- lemoncucumber 5y agoYes, I was simplifying — the important part is keeping the untrusted code off of a trusted network. If you want to do the legwork of carefully segregating things then of course network access can work. I didn’t mention containers since they don’t provide strong isolation and some people misuse them as though they do. There’s no harm in using them as another layer of defense, but hardware virtualization provides much better security.
- PLG88 5y agoWhy not just not trust the network or host at all. Put private connectivity inside trusted code using an SDK. Then the trusted apps can only communicate to devices/apps defined and nothing else. Untrusted code cannot access the trusted network as the network is acutally inside the apps/system.
- andrewaylett 5y agoBut lambda as presented here isn't so much as a way for you to sandbox code, but AWS sandboxes your code. If you're needing to execute untrusted code, you need to play the role of AWS in this scenario.
- webignition 5y agoYes, this is what I'm currently doing with a cloud-based website automated-testing system. In my case, code supplied by the end user is compiled into a different language such that I think I can prevent intentionally-malicious activity. Nonetheless, spinning up a VM to create an environment in which potentially untrustworthy code is executed before then destroying the VM seems the safest option.
- bsdooby 5y agoTcl's possibility to use a restricted child interpreter and the active file pattern come to mind.
- tyingq 5y agoPerl does ship a sandbox module called Safe as a standard module, though I don't know how strong it is.
- blacksqr 5y ago"The Safe module does not implement an effective sandbox for evaluating untrusted code with the perl interpreter." https://perldoc.perl.org/Safe https://perldoc.perl.org/Safe
- tyingq 5y agoYeah, though in this case, whitelisting opcodes probably would have at least avoided qx and ``(both exec()). Avoiding the eval() altogether would be the right path, of course.
- tester34 5y agoOf course, we are Google. /s Have you tried writing your own interpreter?
- niros_valtos 5y agoIf the user is trusted but the environment isn’t, the user can sign the string and you can validate it pre execution. If the user is not trusted, you need to contain the execution as much as possible, e.g. container without file or network access to your resources. If there is a need to access specific resource, white list it.
- aasasd 5y agoWhen people actually want just a subset of `eval` to permit some custom computation, the proper thing to do is to define that subset as a language and make an interpreter that will read only that language. As for mostly-full-featured `eval`: iirc Perl itself has a facility to create restricted sub-interpreters and run scripts that can't do certain things. (Though I might be confusing Perl with PHP here.)
- tinco 5y agoAlmost all modern programming languages have parsers for that language either as a standard library feature or as a package available in the ecosystem. That means it's very easy to run a production quality parser over an input string and then validate and the interpret the resultant AST as you see fit. Besides that approach, simply rolling your own parser using a parser combinator library is super simple. The word combinator makes it seem complicated, but it's actually the opposite, using parser combinators is a lot simpler than writing a parser the traditional way you might have learned in formal education. Implementing a simple DSL like for example an event-filtering language should cost a competent but fully inexperienced programmer maybe 1 or 2 weeks for a proof of concept, and then 3-6 more weeks to get it production ready depending on the feature set of course. Of course, that's more time than simply running the V8 interpreter over your input string, and maybe running the V8 interpreter over your input string is an awesome way to empower your (trusted) customers.
- franga2000 5y agoBasically, just use this: https://github.com/judge0/judge0 https://github.com/judge0/judge0