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.