4 ms·
>The tricky bits are all the hacks to limit resource usage which took a bunch of engineering time to implement and test and aren’t reusable across engines. Int
by regecks 8y ago
>The tricky bits are all the hacks to limit resource usage which took a bunch of engineering time to implement and test and aren’t reusable across engines.
Interesting.
I built the same thing. Through some basic script examples, such as `while(true) {}` or `new Buffer(1000 * 1000);`, the conclusion that I came to was that it is impossible to truly interrupt/prevent resource exhaustion attacks. A bug anywhere that would allow reflection to be accessible would have been disastrous as well.
In the end, I built a JNI wrapper over Duktape+flatbuffers, which gave me super fine-grained control over memory allocation and CPU time.
I'd be very interested to hear a summary of how/whether you managed to make Nashorn safe for user scripts.
- foobarbazetc 8y agoWe run the user supplied code through an instrumentation pass (using Google Closure Compiler) where we modify it at the AST level to call a resource check/interrupt check after every instruction. It also modifies any loop constructs. The compiler will save a sourcemap so you can pretend you’re not modifying user code. We disable all extensions. We do some instrumentation on string ops as well. We use the mbean API to get the memory and CPU usage of the current thread. We have a monitor thread that checks that for all worker threads. I’ve probably forgotten a bunch of things but it was a huge pain. I’m going to tell our guys about your solution and see if that’s something we can look into.
- Tobba_ 8y agoWouldn't code instrumentation be trivially bypassable using an eval construct? esp. something like []["constructor"]["constructor"]("while (true) { }")() Or does Nashorn have a mechanism for forcing the code static?