views:

1010

answers:

8

Hello,

I am using create_function to run some user-code at server end. I am looking for any of these two:

  1. Is there a way to sanitize the code passed to it to prevent something harmful from executing?
  2. Alternately, is there a way to specify this code to be run in a sandboxed environment so that the user can't play around with anything else.

Thanks!

+2  A: 

You cannot reliably sanitize the user input - a determined hacker will find some obscure way to circumvent your sanitization code.

Sandboxing could be possible, but is equally crippling. If you really want to be safe, you should create a sandbox for each call. After all, someone could execute bogus code that is harmful to all other users of your sandbox.

I don't think you really want to allow that. Think of it this way: you are providing programmatic access to the server!

soulmerge
+2  A: 

You could use the tonkenizer to figure out what the code will do, then whitelist certain functions and operations. I think it would end up being very difficult (or impossible) to make it foolproof, especially given PHP's flexibility:

$f = "shell_exec";
$arg = 'rm -rf /';

$f($arg); // ouch
call_user_func($f, $arg); // ouch
eval("$f('$arg');"); // ouch

$newF = create_user_function('', "$f('$arg');");
$newF(); // ouch

The only kind of sandbox that will give you 100% security (well, 99.9%...) is a virtual machine you can just throw away afterwards.

Greg
A: 

You could consider creating a custom(ized) language that your users can make use of. Then it's up to you to create the library of supported functions that could very well be just wrappers of PHP's native functions. But even then, making it hack-proof or simply working is a tedious job at best. Perhaps you should re-evaluate why you want users to have code access in the first place? I'd love to help out if you need someone to discuss this with (or update your question, I guess? :)

Hope you can work it out!

-Dave

Dave
I am really looking for a way to create simple but expressive conditional expressions that users can write easily. However, we are short of time, and churning out a grammar etc. isn't really much of a choice.
kpowerinfinity
you could consider writing a small library of actions that users can/want to use, and force the sandbox to only allow these custom functions. Any other (direct php) function request would result in a failure, but your_trim() and your_str_replace() (for example) work fine. It'll mean that you have to create these custom functions/wrappers, but it shouldn't take too long, I hope..?
Dave
If creating an infix grammar is too hard, make a prefix grammar, which should be easier. I wrote one for my templating engine in a few dozen lines of Icon.
staticsan
+2  A: 

You could try using Quercus, a Java based PHP interpreter, to create a safe sandboxed PHP environment. You can do the same for JavaScript using Rhino, so I think it might be possible with Quercus.

Jani Hartikainen
+1  A: 

">alert("HAHAHAHA");

asdf
A: 

Overall bad idea and too dangerous IMO, no matter what protections you put into place. Better create a pseudo-language limited to exactly what users are allowed to do.

Pekka
Well, that's not what is asked for is it? There are use cases where this could be useful. This could for example be used in an educational institution.
Kimble
A: 

We use the tokenizer to analyze code statically, as well as modify the code to perform runtime checks for certain things. This is done with the tokenizer and scripts based on the tokenizer. Since the tokenizer is the same one PHP actually uses, it improves your luck over writing your own.

I've seen people using regexes to try to analyze a language. This is a really bad idea.

But ...

Since PHP is a pretty stupid-easy grammar, and you have access to the tokenizer, you can actually stop most of the badness by disallowing variable functions, and only allowing a small number of whitelisted functions to be called. If you don't need OOP, even better.

However, we don't feel confident enough that we nailed 100% of the problems, and we use this to power a sandbox for the backend users who are paying customers, not every user on planet earth with a keyboard, and perhaps malice.

I too think the people here who poo-poo the idea 100% as "bad practice" need to get a clue. There are reasons to do this.

Jaimie Sirovich
A: 

http://php.net/runkit

Fabien Bernede