Execute PHP code with restrictions
We have a CMS editor where php is allowed to be used inside it, however we need to restrict access some commands such as file_get_contents, file(), and global.
Can someone help me with a boolean response regex for that? The text from the template is stored in a string.
I kn开发者_如何学Pythonow, probably not an ideal method for this but it's all I can come up with for now :)
What you want to do is pretty much impossible. It is really hard to protect yourself against attacks if you allow people to execute code on your machine.
Here is the try I had on it: Sandbox. Source code.
What it does is basically maintain a large list of blacklisted functions for filesystem access, shell access, a.s.o (I allowed some functions for reading the filesystem like show_source
that should not be allowed if you want to use it for something real.)
It also tries to protect from more hidden attacks like $func = 'unlink'; $func(__FILE__);
by turning it into $func = 'unlink'; ${'___xyz'.!$___xyz=Sandbox::checkVarFunction($func)}(__FILE__)
a.s.o.
PS: Still you probably don't want to allow people to run PHP code on your site. The risk is just by far too big. Instead I would allow people to use a templateing language inside the editor. A good candidate would be Twig, because it has a built in sandbox which allows you to restrict usage to certain tags, functions, ...
It's going to be very hard to protect yourself perfectly.
As I see it, you have a few options:
Search for predefined strings which is not allowed in your content (like file_get_contents) and display a error message saying that the user cannot save because of this. This will however lead to "hacks" where you'll end up searching for all possible characters, like
()
which can be valid in some cases.Use token_get_all and try to parse the content as PHP. You can then loop through the whole source code, token by token, and see if you find a token you do not accept.
Write your own language or DSL for this. This language should only be capable of doing exactly what you want. Depending on your requirements, this can be the easiest and most maintainable way to go.
You can use preg_match for this. Use:
if(preg_match("#(file_get_contents|file)\(#i",$text))
精彩评论