All,
The product that I'm working on allows you to run JavaScript code on the server side via Mozilla's Rhino. One of the reasons why I've gone this route is I want to make it extremely easy for the user to build on top of the data that I index for them. I have a lot of index data that can be used to create some really useful tools so I want to make it as easy as possible for users to hack on top of it.
What I've done so far to mitigate the security risks are:
- Prohibit all access to the java core library. I do this by rejecting all scripts that contains the pattern "java." which are not in quotes. That is, everything that is not in a string.
- I/O access such as reading/writing to files/database are abstracted. Everything has to go through my API.
- Global variables that are used to store java core library objects like the database handle are randomly named at the start of every script execution.
- The database user/password that is used in the JavaScript is also different and has restrictive access as controlled by the database.
- I restrict the number of times that you can iterate in a for/while loop. I haven't decided on the number but I'm thinking about 1000 iterations as being the max by default. The system admin that installs my product can customize this to their internal needs.
- Prevent users from creating functions. I don't want a situation where they can create an infinite loop like.
function a() {
b();
}
function b() {
a();
}
This may be too restrictive so I may do the same thing that I do with the loops and just restrict the number of function calls that you can make.
- Prohibit the use of eval statements. In order to convert a JSON to an object, you will have to go through my API, which means I will only eval JSON strings that are in format that I expect.
So this is what I've implemented so far. Am I missing anything else?
Thanks
I didn't go down the route of trying to restrict the user from creating functions and eval'ing etc.
It was easier to just run 'unsafe' scripts in a seperate sandboxed process with their own own (restricted) globals. I gave the scripts limited time to run before the process was forcibly killed. Doesn't matter about infinite loops and other things so much then.