views:

221

answers:

7

I want to let users test out a PHP class of mine, that among other things crops and resizes images.

I want them to write PHP code in a text field, send the form, and then their code will be run. How can I do this?

Or is it other safe ways to let users (anyone) demo a PHP class?

+1  A: 

You could possibly use eval http://us2.php.net/manual/en/function.eval.php

John Boker
This would work but is very dangerous.
Brian Ramsay
It is not very dangerous, it's extremely dangerous.
Time Machine
It's only dangerous if you don't take some precautions.
Alex R
+4  A: 

Yes. You can use the eval statement in php (linked earlier by John http://us2.php.net/manual/en/function.eval.php), however be very careful. You really don't want users to be able to run code on your machine freely.

My recommendation would try to come up with a different approach to do demos - perhaps a flexible few examples... but don't let them run code directly

Dave Morgan
Yeah, everyone says using eval() is scary. Wouldn't let them do that! I think I'll just make a couple of demos!
rebellion
+5  A: 

I would spawn the PHP process using a user account with next-to-no permissions. Give the read-write access to a single directory, but that's it.

You're still opening yourself to DoS attacks with infinite loops and such, but if you absolutely must do it, then run the code in this very-low-permissions sandbox like IE and Chrome do.

Using EVAL is probably the worst idea.

Frank Krueger
If you run the untrusted code in a VM, infinite loops etc are a non-issue.
Alex R
+3  A: 

You could use the eval() function, but don't do it. Seriously.

There's no "safe" way to let any old user run their own PHP on your server. You are exposing yourself to a potential world of hurt.

Instead, provide excellent documentation, code samples, and the source for your own demos, and encourage potential users try it out on their own test/development servers.

Chris
+2  A: 

As it was already stated, you could use eval function, but it's very dangerous. If you want users to test the code, prepare demo pages presenting possible usage, and for instance possibility to add parameters by user via HTML forms.

leafnode
A: 

Don't think in terms of PHP or another general-purpose language, think of the minimal language that's sufficient to express the operations in your domain of image processing. Users submit expressions in this domain-specific language (DSL), these expressions are parsed on the server side and passed to your code.

The important thing initially is to think about the range of image-processing operations and how they can be combined. That will tell you how expressive the language has to be. Once you've worked that out, there are plenty of choices for how the language would look syntactically. The syntax of the language might depend on a tradeoff between ease of use and ease of parsing.

If you can write or find a parser for expressions of this kind, it might be the easiest for users. Actually, can anyone recommend an existing expression evaluator that would work in cases like this (for example, can Smarty safely run user-submitted expressions?), or indeed a parser generator for PHP?

resize(rotate("foo.png", 90), 50)

A language like this might be less easy for users, but it can be processed using a fairly simple stack machine:

"foo.png" 90 rotate 50 resize

Even easier, an XML-based language like this doesn't need its own parser:

<resize percent="50"><rotate degrees="90"><img src="foo.png"></rotate></resize>

Using a DSL doesn't protect you from domain-specific attacks, for example somebody might use the language above to resize an image to a zillion pixels and use up all the server memory. So there would have to be some sort of runtime environment for the DSL that puts limits on the amount of resources any user-submitted script can use.

d__
A: 

You can use eval, but not without some precautions.

If your security concerns are merely "cautious" as opposed to "paranoid", you do have a few options:

  • If you have a dedicated Apache/PHP instance just for this project of yours, set the disable_functions option in php.ini and turn off all file and network related functions. This will affect the entire PHP installation and will break some surprising things, like phpmyadmin.
  • If you don't have a dedicated server, try 'runkit': http://php.net/manual/en/book.runkit.php to disable functions only within an already running script.
  • Perhaps more work? Setup a virtual machine (VirtualBox, VMware, etc) which is aggressively firewalled from within the Host OS, with a minimal allocation of memory and diskspace, and run the untrusted code there.

If you are paranoid... setup an approval process for all uploaded code.

Alex R