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?
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.
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
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.
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.
You could possibly use eval http://us2.php.net/manual/en/function.eval.php
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.
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.
Related
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:
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.
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.
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?
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.
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.
I admit the title is mostly a catch 22, but it's entirely relevant, so please bear with me for a while...
Background
As some may know, I'm working on a PHP framework whose major selling point is that of bridging functionality between different CMSes/systems.
From a developer perspective, there's an extensive error handling and logging mechanism.
Right now, there are two settings, DEBUG_MODE and DEBUG_VERBOSE, which control debug output.
The mode describes the medium and verbose controls the amount of detail.
To make it short, there's a mode called "console" which basically dumps debug info into the javascript console (which is now available in a major web browser near you).
The Issue
This [debug system] works great for development servers, but you absolutely cannot use it on a production one since debug details (which include DB credentials etc) get published publicly. And in all honesty, who ever migrated from a dev. to a prod. server flawlessly each time?
Solutions
Therefore, I've been trying to figure out a way to fix this. Among my proposed solutions are:
Having a setting which tells the framework to enable logging only if the request comes from a certain IP. The security issues for this are quite obvious (IP spoofing among others).
Having a setting which contains PHP expression(code) that gets eval'd and it's return used as a yes/no. The best part is that the framework installed may suggest CMS-specific expressions, eg:
Wordpress: current_user_can('manage_options')
Joomla: $user=&JFactory::getUser() && ($user->usertype=='Super Administrator') || ($user->usertype=='Administrator')
Custom: $_SERVER['REMOTE_ADDR']=='123.124.125.126'
These are among the two, I'm eager to hear out more suggestions.
So, do you think eval() should be up to it? I'll ensure it still performs well by only doing this once per page load/request.
Clarification
if(DEBUG_MODE!='none')echo 'Debug'; // this is how it is now
if(DEBUG_MODE!='none' && $USER_CONDITION)echo 'Debug'; // this is how it should be
The $USER_CONDITON allows stuff such as running is_admin() to allow all admins to see debug info, or, getUser()->id==45 to enable it for a specific user. Or by IP, or whatever.
Go ahead. It's evident that you understand the hypothetical security implications. In your case it's just important to tell the target user base about it.
As for the practicability of your approach, there's no discussion really. You need variable authentication logic and can't hardwire it to one specific environment/cms runtime.
The only concern you see is about performance. That's baloney. Not an issue. The presence of eval is what discerns scripting languages from compiled languages. If it's available you can not only use it, but can be sure that it's not going to be slow because a compiler+linker run is required behind the scenes. PHP takes some time with initializing its tokenizer and parser, but parsing itself is surprisingly quick.
And lastly, avoid such question titles on SO. ;} Or at the very least talk about create_function please.
IP spoofing long enough to actually get a response is unlikely to occur. If a user manages to build up a connection to your server, spoofing an internal or privileged developer IP they control your router, so you've got other things to worry about.
Rather than running eval can't you just write an anonymous function/closure: http://php.net/manual/en/functions.anonymous.php
(putting it in a config file, rather than web screen, writing complicated PHP code on a web form seems sub-optimal anyways)
Allowing free-form input of PHP code that gets executed - be it through eval() or create_function() - is simply bad design, and opens a big potential vulnerability for no good reason. It also opens the possibility of crashing a page through syntax errors.
Even the argument that the administrator can install plugins anyway doesn't hold entirely, because XSRF attacks are conceivable that manage to get malicious stuff into a text field (one request), but can't trigger a plug-in installation.
So no, I wouldn't do it; I would implement each CMS bridge as an adapter instead, and let the user choose the adapter (and if necessary enter some custom, sanitizable settings) from a pre-defined list. (Something similar was also suggested by #Wrikken in the comments)
It's your call. Chances are you will never have a problem from doing this the eval() way. And it can be argued that most of the CMSs you will be connecting with (Wordpress, Joomla) allow arbitrary execution of PHP code in the back-end anyway. But it's not good design.
Having a setting which contains PHP expression(code) that gets eval'd and it's return used as a yes/no. The best part is that the framework installed may suggest CMS-specific expressions, eg:
eval() may crash your page if any function doesn't exist or on any number of parse errors. And if bugs exist which allow user-supplied input (such as a uri requested) to even touch these evaled values, it will potentially open up your site to malicious or accidental destruction. Instead to identify the currently working framework, look for markers in the framework you're trying to bridge to, such as certain constants, functions, classes, etc. You can replace all your eval() functions with safe checks using function_exists(), defined(), etc.
I was wondering what steps you use to keep downloaded plugins from being malicious?
For example, what does wordpress do to ensure that the plugins you download do not simply execute unlink('/')
I'm assuming it partly depends partly on downloader to install plugins to use his or her own discretion, but do plugin systems take measures to minimize the security risk of running 3rd party plugins?
Thanks!
Matt Mueller
Simple answer: you can't do this programmatically. Simply can't be done. Certainly Wordpress has a validator of some sort to determine whether the plugin is outright nasty, but there's no way to say for certain that it is safe.
I'm an intern at Mozilla this summer and I'm working on the validator that scans add-ons as they're submitted to addons.mozilla.org. I can only imagine that Wordpress has a very similar tool on their end. The idea is that the app outright rejects blatantly malicious code (eval("evil nasty code");), while the rest of it is analyzed with some simple heuristics. The algorithms in place mark down some potential red flags based on what it sees in the add-on package and submits those notes to the editors, who then review the code. It effectively ends up being a human-powered process, but the software helps to take care of a lot of the heavy lifting.
Some techniques that the Mozilla validator uses:
Syntax checking
Code and markup parsing (HTML/CSS) to find remote code vulnerabilities
Javascript parsing and analysis (parse the JS to an AST tree and analyze each statement, evaluating static expressions as deeply as possible)
Compatibility/deprecation testing
You can check out the code here:
http://github.com/mattbasta/amo-validator
Hope this helps!
unlink('/') wont do any harm since it only deletes files, you would have to use rmdir or more precisely a recursive rmdir implementation. I don't think there is any way to prevent malicious code from being executed because there are many ways of being malicious. You can restrict certain functions from being called in php.ini but that will only help you to a certain point. For instance, str_repeat and unserialize are common functions but if called with the right arguments they can exaust all the memory allocated to your PHP scripts in no time. But this is only an example, a more nefarious one could act as a backdoor or email all the logins to the developer. I guess in the end you'll have to trust the developer and the community if you don't want to audit the code by yourself.
There are tools for PHP that do Static Source Code Analysis in order to find vulnerabilities. Open source analysis tools for php include RATS and PHP-SAT.
If you have ever used a Static Source Code Analysis then you know that these tools will produce a TON of false positives and false negatives. No Source Code Analysis tool can tell you 100% weather or not a program has a backdoor or can be malicious. If it could then we wouldn't have so many problems with websites getting hacked. Wordpress its self is extremely insecure, so are all of the plugins, and this is because of mistakes, not malice.
Malicious code can be obfuscated, hidden and take on many many forms. Trying to find an accidental vulnerability is a whole lot easier problem than an intentional one. A backdoor in PHP can be as simple as adding or removing 2 bytes.
Removing 2 bytes:
$id=mysql_real_escape_string($id);
"select * from test where id=$id"
vs
"select * from test where id='$id'"
or adding 2 bytes:
`$_GET[b]`;
We have an application that is written in PHP that we are going to license to a customer. Our company believes that the customer might intend to steal the source code and create their own fork of the software, therefore we want to encrypt the source code.
I have searched some for PHP-encrypters and found several that seems good, but since we have no previous experience of PHP-encrypters it hard to say which one is the best. Which PHP encrypters have you used and what is your experience?
So, First:
It is impossible to encrypt your entire code base because at some point there has to be an eval statement, and if the user changes the eval to an echo, they get all of your code in the browser.
And here is a bunch of people who agree with me.
Furthermore:
People will offer you obfuscators, but no amount of obfuscation can prevent someone from getting at your code. None. If your computer can run it, or in the case of movies and music if it can play it, the user can get at it. Even compiling it to machine code just makes the job a little more difficult. If you use an obfuscator, you are just fooling yourself. Worse, you're also disallowing your users from fixing bugs or making modifications. - Schwern
Now thats done:
Bytecompiling is something completely different than encrypting. It makes the PHP code into already interpreted bytes, similar to an exe file. You can include these files just like any other php file.
The byte code produced is able to be reverse engineered, but it would take lots of time and is not worth the company's time.
Check out the byte compiler PHP extension.
I'd also like to note that PHP comes with several ways of reverse engineering classes. Such as the Reflection Class. This basically allows people to see every method, variables, and constant in each of your classes without the need for your source code.
Frankly, once someone sees the functions you use, it is pretty easy to piece it together after that.
There's a lot of obfusticaters out there masquerading as encrypters.
If you really must encrypt your code use Zend.
IMHO shutting your customers out of your code is inherently evil and would rather hide some symbology in the code and sell it under a no-modify/re-sell contract. Then sue the ass off them if they try to sell it on. You could argue that encrypting your code closes down a business opportunity ;) !
C.
I am wondering what security concerns there are to implementing a PHP evaluator like this:
<?php eval($_POST['codeInput']); %>
This is in the context of making a PHP sandbox so sanitising against DB input etc. isn't a massive issue.
Users destroying the server the file is hosted on is.
I've seen Ruby simulators so I was curious what's involved security wise (vague details at least).
Thanks all. I'm not even sure on which answer to accept because they are all useful.
Owen's answer summarises what I suspected (the server itself would be at risk).
arin's answer gives a great example of the potential problems.
Geoff's answer and randy's answer echo the general opinion that you would need to write your own evaluator to achieve simulation type capabilities.
don't do that.
they basically have access to anything you can do in PHP (look around the file system, get/set any sort of variables, open connections to other machines to insert code to run, etc...)
The eval() function is hard to sanitize and even if you did there would surely be a way around it. Even if you filtered exec, all you need to do is to somehow glue the string exec into a variable, and then do $variable(). You'd need to really cripple the language to achieve at least some sort of imaginary security.
could potentially be in really big trouble if you eval()'d something like
<?php
eval("shell_exec(\"rm -rf {$_SERVER['DOCUMENT_ROOT']}\");");
?>
it's an extreme example but it that case your site would just get deleted. hopefully your permissions wouldn't allow it but, it helps illustrate the need for sanitization & checks.
There are a lot of things you could say.. The concerns are not specific to PHP.
Here's the simple answer:
Any input to your machine (or database) needs to be sanitized.
The code snippet you've posted pretty much lets a user run any code they want, so it's especially dangerous.
There is a pretty good introductory article on code injection here:
Wikipedia on Code Injection.
If you allow arbitrary code to be run on your server, it's not your server any more.
Dear god NO. I cringe even at the title. Allowing user to run any kind of arbitrary code is like handing the server over to them
I know the people above me already said that. But believe me. That's never enough times that someone can tell you to sanitize your input.
If you really, really want to allow user to run some kind of code. Make a subset of the commands available to the user by creating some sort of psudo language that the user can use to do that. A-la the way bbcode or markdown works.
If you are looking to build an online PHP interpreter, you will need to build an actual REPL interpreter and not use eval.
Otherwise, never ever execute arbitrary user code. Ever.
Do NOT allow unfiltered code to be executed on your server, period.
If you'd like to create a tool that allows for interactive demonstration of a language such as the tool seen here: http://tryruby.hobix.com/ I would work on coding a sub portion of the language yourself. Ideally, you'll be using it to demonstrate simple concepts to new programmers, so it's irrelevant if you properly implement all the features.
By doing this you can control the input via a white list of known acceptable input. If the input isn't on the white list it isn't executed.
Best of luck!
As already answered, you need to sanitize your inputs. I guess you could use some regex-filtring of some kind to remove unwanted commands such as "exec" and basically every malicious command PHP has got to offer (or which could be exploited), and that's a lot.