I want to limit what PHP functionality my users have access to.
For instance there is an object $data and the user likes to use if for and echo.
Obviously allowing him to write PHP would be a serious vulnerability.
Is there any way to run this PHP in a sandbox or would you recommend any lightweight PHP template engine?
If you don't have your own server you probably don't have runkit. But what you do have (probably) is Tokenizer! Using the Tokenizer you may look through the given source code and abort if you find an invalid token. Here an example how to validate an array using this. You could do same for your purpose. The PHP documentation has a list of tokens. If you need help deciding which tokens to allow or to disallow, please say so.
€dit: And obviously I do recommend to use Twig, too. It is so nice - and has sandboxing!
The only one I know so far is runkit.
The runkit extension provides means to
modify constants, user-defined
functions, and user-defined classes.
It also provides for custom
superglobal variables and embeddable
sub-interpreters via sandboxing.
Update:
I could find these two links regarding zend and runkit you should take a look at:
http://framework.zend.com/wiki/display/ZFPROP/Zend_Http_Server+-+Mat+Scales
http://www.dunfy.me.uk/?p=38
Along the lines of smarty, give twig a try!
There is also a very robust extension system which allows you to allow/disallow built-in or custom tags, token parsers, nodes, etc in the template language itself. This way, users can have basic logic (conditional statements, "functions" (blocks) and iterators) without resorting to the evils of eval.
Tried Smarty? http://www.smarty.net/
The PECL runkit extension does provide sandboxing, but it's possibly a bit overkill for what you want to do
PHP Fat-Free Framework has a template engine that prohibits the use of PHP code and allows you to define which functions can be used inside HTML templates.
There's also a real sandboxing feature that makes functions and include files independent of others, i.e. variables/functions in one include file are not known to others, so you can have a function with an identical name as another include file. This may be of some use for (dysfunctional) developer teams.
Related
I want to build a report builder into a web app of mine. The user collects data through other parts of the site, and then should be able to generate "reports" in which he/she can use said data in a document-style fashion. I want the user to be able to use basic math functionality, get/set their own variables, etc. I figure why reinvent the wheel? If I were to allow the user to write the report with something like Twig Template Engine and only enable certain extensions for them to use, does this seem reasonably secure? Twig templates already remove any php found in the markup, and there aren't too many powerful functions that you can use, other than basic string alterations, etc. Let me know your thoughts.
Twig has a fairly powerful sandbox extension that does exactly what you're describing. With a sufficiently stringent security policy, I can't see any problems here.
If twig does what you need, why not? It's pretty well done, has a sandbox mode and can compile the templates. In the opposite, offering PHP from PHP is hard to divide, so using some template sounds not bad to me.
While I have been reading through countless posts about using PHP as a template engine (using output buffering), I'm still trying to make a case for it.
As I'm wondering if I could use PHP as a template engine for a web app (users will be able to change the layout themselves) -- I still don't find any info regarding the following:
Store the templates in a MYSQL database
Eval them
BUT only include functions that are whitelisted (to give them only access to a limited set of functions -- while, foreach, etc ...)
Anybody looking for the same solution, but can chime in with a bit more information? That would be quite nice.
If you can't trust the user editing the template, you are better off using a separate templating language.
Note that many template languages like Smarty provide code execution functions as well. You may need to disable those in the engine's configuration.
Disabling all potentially dangerous functions in PHP is a very arduous task, and easy to screw up. See Exploitable PHP functions
PHP is not suitable as a template engine for your purpose. You should use a proper template engine with sandboxing support for that: Twig.
That is probably a quite difficult (but interesting, if you are into the topic) task, because it involves building a small PHP parser, which can flawlessly identify any function call or method call (because if you miss one, you're screwed/hacked/...) and then check if all your matched function identifier tokens are in your whitelist, and otherwise deny eval-ing. For generating your Parser, you might want to check out the PHP_ParserGenerator, which unfortunately does not seem to be maintained anymore, or lemonPHP/JLexPHP, which may be more up to date, but you need to use Java to generate the Parser.
Because of all this is a quite tedious task, most people resort to using a custom (made-up) template language, which is similar to PHP, but not identical.
Popular PHP template engines are, among others:
Smarty
Twig
PEAR Template Engine
Savant
More can be found here and here
Here's something I've thought about for a while.
I am creating an application where's my users will upload their own custom themes, which means that there's going to be a good opportunity for anyone with basic PHP/XSS/whatever skills to cause a lot of headache.
I would like to run any uploaded files in a sort-of sandboxed, closed environment that only has access to the stuff (variables) that I want and nothing else.
Would this be good practice and how would it be done?
To allow arbitrary html/javascript safely then each user must have its own subdomain. If each user has their own subdomain then a user's JavaScript will be restricted their own sandbox because of the Same Origin Policy. If you only want to allow "safe html" then htmlpurifer is an option, and then you can use 1 domain.
Allowing custom PHP is a bit more hazardous. "Shared hosting" providers rely upon suPHP which forces the php script to run as a specific user. This would require every user to have their own account on your system. This method of defense has been around for a while. It isn't perfect but it does the trick.
Another possible solution for custom themes is to use a templating engine, which can prevent templates from getting full access to PHP. SOme popular frameworks for this:
smarty, it doesn't have the best secuirty track record, but you keep it up to date you probably won't have a problem. It needs to be configured to disallow native php.
twig is a relatively new engine from the makers of Symfony Framework. This means it has a decent developer base and since it ships with Symfony, it's also been tested in the wild. Twig does not allow any PHP functions to be called, unless you specifically create a twig function/filter for them.
As you don't want to grant your users access to PHP, you should use a template engine that supports sandboxing. Twig is a prominent example here.
global scope will always be accessible.
but object oriented concept provide a lot. what you can't do is to hide global stuff. what you can do is not make it visible in the first place.
but executing unreviewed 3rd party code is a tricky thing. i would recommend some sort of process isolation here if possible. which means you open a process using popen or something, in combination with suphp you can make a restricted linux user. that is very well possible and secure with the correct security measures in place.
a good approach to run the code within the same program is to use the templating pattern. its a bit unpractical for classes because whole files get loaded that can inject hazardous code. but you can create custom functions in php from code. the code does not get executed unless the function is called. you can also extend a class to a variable name, which is then user supplied code. however this is almost unpossible to make safe.
when it comes to html code , it is way easier. there are good html tidy is a good start. there are good solutions to allow only speical tags.
javascript can be "secured" in a way that old facebook fbml applications did. which includes server side rewrites, dynamic variable names etc its quite complicated.
in my opinion the best way to allow external customizations is to allow external stylesheets. just load them from an external origin and there is not really a security concern.
edit: of course you can parse any code and limit it to certain statements or deny certain statements, but this is very tricky and for php a very heavy constraint. its probably better to switch to some higher level algorithmic languages or go client side with javascript.
What you want to do is really risky. You should never allow your users to upload PHP files. That's why you don't find many PHP fiddlers around the net (though now there's some).
Also JS is dangerous in some indirect ways and pretty much nobody allows you to upload it (with the notable exception of Tumblr).
What you should do is adopt some kind of templating engine, and sanitize the templates the users upload, to remove scripts.
Since security is an issue, try to check security advisories like Secunia when choosing the templating engine.
I wrote a small PHP application that I'd like to distribute. I'm looking for best practices so that it can be installed on most webhosts with minimal hassle.
Briefly: It's simple tool that lets people download files once they login with a password.
So my questions are:
1) How should I handle configuration values? I'm not using a database, so a configuration file seems appropriate. I know that other php apps (e.g. Wordpress) use defines, but they are global and there is potential that the names will conflict. (Global variables also have the same problem, obviously.) I looked at the "ini" file mechanism built into PHP. It only allows comments at the top - so you can't annotate each setting easily - and you can't validate syntax with "php -f". Other options?
2) How to handle templating? The application needs to pump out a form. Possibly with an error message. (e.g. "Sorry, wrong password.") I've have a class variable with the HTML form, but also allow an external template file to be used instead (specified in the config). I do some trivial search and replace - e.g. %SCRIPT% to the name of the script, %STATUS% to hold the error message. This feels a bit like reinventing the wheel, but including a templating system like Smarty is overkill. (Plus they may already have a templating system.) Other options?
3) i18n - There are only 3 message strings, and gettext doesn't seem to be universally installed. Is it such a bad idea just to make these three strings parameters in the config file?
4) How to best integrate with other frameworks? My app is a single class. So, I thought I could just include a php script that showed how the class was called. It would be a starting point for people who had to integrate it into another framework, but also be fine as-is for those not interested in customizing. Reasonable?
5) GET/POST parameters - Is it bad form for a class to be looking at $_GET and $_POST? Should all values be passed into my class during construction?
Thanks.
Configuration
You can use a php file like this:
<?php
return array(
'option1' => 'foobar',
'option2' => 123,
//and so on...
);
?>
And in the main class just use:
$config = (array) include 'path/to/config/file';
And if you plan to mostly distribute your class as a component in other applications, then simply put config array/object as a parameter in your class' constructor and leave the details to the user.
Templating
For such simple application the method your described should be enough. Remember that one can always extend your class and overload your outputting method with his own.
I10N
As mentioned before, for 3 variables anything more than storing them as config is just overkill.
Integration
Comment each public method (or even better also protected and private ones) with explanations what do they do and what parameters are needed. If you combine that with an example, it should be enough for most users.
GET vs POST
Your class uses passwords and you even think of sending them via GET? ;)
Think of browser history, referer headers etc - your users' passwords would be visible there.
Can config be local to class instances? Or could you create a little class that you could create an instance of to query for config values? Also prepending any global vars with you application's name should go some way to stop clashes.
If your templating is really simple, just write a short templater. It'll be easier than trying to fend off problems people get with any 3rd party templater. It might also simplify licensing issues. If you start worrying about what they already have, you'll never release anything. There are too many combinations.
For 3 strings? Yeah do those the same way you're handling config.
Good comments throughout with an intro explaining how you use the class.
I don't think so. If it bothers you, you could use default arguments to use given arguments first, then search for GET/POST values if none are provided (though that might be a security risk)
There are other things to take into consideration. Lots of people are on shared hosts and as a result, don't have control over their php.ini or their php version. You need to make sure you're only using features that are as commonplace as possible.
One example is that shorttags aren't enabled on some hosts (you have to use <?php ... ?> and <?php echo "..."?> instead of <? ... ?> or <?= "..." ?>) which can be a royal PITA.
In addition to Krzysztof's good advice:
Use <?php only
If you use functions that can be disabled, use function_exists() to ensure they're available. #missing_function() makes PHP die silently without any error logged.
You can't rely on things that can be disabled/changed via php.ini. Use ini_get() to adapt to different settings.
If magic_quotes are enabled, strip slashes only on from your copy of input – don't modify global arrays! Security of some lame code may rely on these slashes being present.
Expect that users will mindlessly copy&paste code from your documentation/website.
Other than standard OO concepts, what are some other strategies that allow for producing good, clean PHP code when a framework is not being used?
Remember: MVC, OOP and tiers are design concepts, not language constructs, nor file-structuring.
For me, this means that when not using a framework, and when there's not different teams for programming and designing; there's no value in using another template system on top of PHP (which is a template language). Also, separating code from layout doesn't necessarily mean doing it on different files.
This is how i used to do for one-off, seldom expanded, PHP web apps:
write a 'general utilities' file, there i put some formatting/sanitising functions, as well as a few DB access functions:
getquery(): given a SQL, returns a result object
getrecord(): given a SQL, returns a record object (and closes the query)
getdatum(): given a SQL, returns a single field (and closes the query)
put all configurations (DB access, some URL prefixes, etc) on a 'config.php' file
write a model layer, either one file, or one for each object you store on DB. There, will be all the SQL constants, present a higher-level API, based on your conceptual objects, not on DB records.
that's your 'framework', then you write the 'presentation' layer:
one PHP file for each page, starts with some simple code to fetch the objects needed, followed by HTML with interspeced PHP code, just to 'fill in the holes'. with very few exceptions, the most complex code there should be for loops. I make a rule to use only one-liners, the ?> should be in the same line as the opening <?php
each data-entry form should point to a small PHP without any HTML, that simply get's the POST data, enters into the DB, and forwards to the calling page.
and that's it. If working alone, it has all the separation of intents you need, without drowning in a lot of files for a single user action. Each page as seen by the user is managed by a single PHP file.
It's even easy to maintain, after a few months without looking at the code, since it's easy to test the app, taking note of the filenames in the URL field of the browser. This guides you directly to the relevant code.
(nowadays, of course, i'm using Django for almost everything...)
If you ever find yourself mixing HTML and code, just STOP. You're, well...
You're doing it wrong! http://dennisjudd.com/albums/cute_cats/wrong_mike.jpg
I'd say pretty much the same as for any other language:
Don't optimise prematurely
Keep methods small
Practise DRY
Practise data-driven programming
Use sensible shortcuts (e.g. ternary operator)
Format your code well so that it can be understood by others
Don't use OO blindly
Always check return codes for errors
Enable the highest warning level and ensure your code doesn't produce any warnings
Be very careful when it comes to typing issues (this goes for all weakly-typed languages). The '===' operator is your friend.
Really this question is quite language agnostic, as it applies to most languages where you choose to "roll your own". Two suggestions I would make would be :
Firstly, just because you aren't using a framework doesn't mean you can't adopt the patterns for segregating code. The MVC pattern is the minimum you should consider when arranging you source code - it makes for a much cleaner and easier to maintain collection of source code, even if the application doesn't entirely follow the routing processes associated with frameworks, having code that "does" things separated out from that which "represents" things is very beneficial.
Secondly, just because you've chosen not to use a full framework, doesn't mean you need to reinvent the wheel. Utilise pre-packaged libraries sensibly in order to solve a specific problems. Two good examples would be a logging framework (log4php) and a front-end rendering/templating solution (Smarty).
Stay away from globals as best as possible :-D
If you really do follow OO concepts, like separation of concerns, your code will be pretty good, but here are a few suggestions:
Framework or not, use MVC.
I can't stress enough how important it is to never mix your logic with your HTML. In an HTML file, PHP should be used only as a template language and nothing more.
Use a DBAL.
Separate your design from your content. A common method for doing this is using CSS heavily and having header and footer files containing the bulk of site layout.
Have a single file for option constants, like DB credentials, FTP credentials, etc.
make sure to follow standard practices of separation of concerns. What this means is try not to mix you business and data layer with your UI.
Even If you don't use a framework, use a template engine. By using templates, you'll seperate the logic and presentation of your application. Then design, code and format the logic part like what you would do with any other language. Make the "designers" design the user interface :)
OO is not strictly necessary: it was possible to write good code in PHP < 5 too. Good procedural code, well separated into files and directories by 'logical distance' should also keep you safe. Notice, though, how this starts resembling OO from afar.
Best thing would be to be consistent: I've seen a project where Smarty was used in most pages except one -the most complex, go figure-.
Take advantage of PHP's in-built extensions - MySQLi for example. As these become more object-oriented the requirement for frameworks becomes less.
For example, I could create a useful TwitterApp by using the following extensions and no actual framework besides a core class to tie instances together.
MySQLi for database (PDO if you need DAL)
SimpleXML for RSS/API reading
Smarty for templating
I might need to make a few helper classes for things like Login but my usual pair of classes (DAL and TPL) are made obsolete by two very well worked extensions.