Icode4food
Icode4food

Reputation: 8694

Server side execution of user submitted code

Here is my situation. I am building an application that contains some heavy mathematical calculations where the formula needs to be editable by a sufficiently privileged, but untrusted, user.

I need a secure server side scripting language. I need to be able to access constants and values from 4+ database tables, the results of previous calculations, define user variables and functions, use if/then/else statements, and I'm sure more that I can't think of right now.

Some options I've considered:

  1. I have considered using something like this matheval library but I would end up needing to extend it considerably for my use case. I would essentially be creating my own custom language.

  2. PHP runkit sandbox. I've never used this before but am very concerned about the security issues involved. Considering the possible security issues, I don't think that this is a viable option.

  3. One other idea that has crossed my mind that I don't know if it is possible would be to use something like javascript on the server side. I've seen js used as a scripting platform in desktop applications to extend functionality and it seems a similar approach may be feasible. I could ideally define the environment that things ran it, such as disabling filesystem access etc. Again, security seems like it would be an issue.

From the research I have done, it seems like #1 is probably my only option, but I thought I would check with a larger talent pool. :-)

If #3 is possible, it seems that it would be the way to go, but I can't seem to turn up anything that is helpful. On the other hand, there may not be much difference between #2 and #3.

Performance is another consideration. There will be roughly 65 some odd formulas each executing about 450 times. Each formula will have access to approximately 15 unique variables a hundred or so constants, and the results of previous formulas. (Yes, there is a specific order of execution.)

I can work with an asynchronous approach to calculation where the calculation would be initiated by a user event and stored in the db, but would prefer to not have to.

What is the best way to work with this situation? Are there any other third party libraries that I haven't turned up in my research? Is there another option in addition to my 3 that I should consider?

Upvotes: 3

Views: 300

Answers (2)

Will Hartung
Will Hartung

Reputation: 118671

There's almost no reason to create a custom language today. There's so many available and hackable, writing your own is really a waste of time.

If you're not serving a zillion users (for assorted values of a zillion), most any modern scripting language is securable, especially if you're willing to take draconian measures to do so (such as completely eliminating I/O and system interfaces).

JavaScript is a valid option. Its straightforward to create mini-sandboxes within JS itself to run foreign code. If you want folks to be able to persist state across runs, simply require them store it in "JSON-like" JS structures that can be readily serialized from the system on exit, and just as easily reloaded. These can even be the results of the function.

If there's a function or routine you don't want them to use, you can un-define it before firing off of the foreign code. Don't want them using "read" to read a file? read = func(s) { }

Obviously you should talk to the mailing lists of the JS implementation you want to use to get some tips for better securing it.

But JS has good support, well documented, and the interpreters are really accessible.

Upvotes: 1

Ira Baxter
Ira Baxter

Reputation: 95352

You have two basic choices:

a) Provide your own language in which you completely control what is done, so nothing bad can happen,

b) Use some other execution engine, and check everything it does to verify nothing bad happens.

My problem with b) is it is pretty hard to figure out all the bad things somebody might do in obscure ways.

I prefer a), because you only have to give them the ability to do what you allow.

If you have a rather simple set of formulas you want to process, it is actually pretty easy to write a parser/evaluator. See Is there an alternative for flex/bison that is usable on 8-bit embedded systems?

It isn't clear to me that you have a performance problem. yes, you want to execute something 450 times; but it includes database accesses, whose cost will dominate any computation involivng a 1000 arithmetic steps. You may find that your speed is limited by the DB access that that you need to cache the DB accesses to get it to go faster.

Upvotes: 0

Related Questions