5

Possible Duplicate:
PHP: How To Disable Dangerous Functions

Hi, this is my situation: I must let my clients enter PHP code, but only safe functions like string function, date function etc. So I need the danger PHP functions list to remove them by using string replace before save to PHP file. Any suggestion?

Community
  • 1
  • 1
StoneHeart
  • 15,790
  • 32
  • 67
  • 84

5 Answers5

7

Forget it. Reliable function whitelisting is not possible in php. Example:

$x = 'e' . str_replace('y', 'x', 'yec');
...lots of code...
$x('format c:');

realistic options are

Community
  • 1
  • 1
NullUserException
  • 83,810
  • 28
  • 209
  • 234
2

As far as I know, you can only use a black-list approach:

Of course, you have to consider how feasible it is to maintain an updated list of all builtin functions defined by all the possible extensions.

Another possibility I can think of is writing a simple tokenizer:

http://es2.php.net/manual/en/function.token-get-all.php

You can then check the functions used against a white list.

Update: I was under the wrong impression that token_get_all() would identify function calls but it actually doesn't. They're all T_STRINGs.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
  • +1, i dont understand why people tend to over complicate issues like these, over-compicating it wont make it safer, stick to the original methods such as `disable-functions` and `disable-classes` – RobertPitt Aug 17 '10 at 09:29
  • @stereofrog, I've figured out what you meant (you don't really say) and edited my post accordingly. – Álvaro González Aug 17 '10 at 09:45
  • PHP.net's token documentation is pretty lacking. They leave out certain tokens and also incorrectly define a few tokens--either that or their usage by `token_get_all()` and by PHP's warning/error messages are different, and they are going by the latter. – Lèse majesté Aug 17 '10 at 10:40
  • @stereofrog: of course, you're right about that. It's not even worth trying. – Álvaro González Aug 17 '10 at 11:07
2

The most secure and easy to maintain option will be to program a dedicated "mini-language" in php. You can make it a subset of php, or make it look like Excel formulas, or even invent your own one. This way you'll always have the full control of what's happening.

//

just for fun, here's a small Lisp for you

function lisp($x) {

    if(is_string($x)) {
        $re = '~\(([^()]*)\)~';
        while(preg_match($re, $x))
            $x = preg_replace_callback($re, 'lisp', $x);
        return trim($x);
    }

    $x = preg_split('~\s+~', $x[1]);
    $e = array_shift($x);
    if(!$x)
        return is_numeric($e) ?  floatval($e) : $e;

    switch($e) {
        case '+':  return lisp($x[0]) + lisp($x[1]);
        case '-':  return lisp($x[0]) - lisp($x[1]);
        case '*':  return lisp($x[0]) * lisp($x[1]);
        case '/':  return lisp($x[0]) / lisp($x[1]);

        case 'concat':  return lisp($x[0]) . lisp($x[1]);
    }

    return function_exists($e) ?
        call_user_func_array($e, array_map('lisp', $x)) : '';
}

$input = '
    (strtolower 
        (concat
            (strrev olleh) 
            (+ 22 20)))';

echo lisp($input); // hello42

;))

user187291
  • 53,363
  • 19
  • 95
  • 127
  • That's potentially a *lot* of work. – NullUserException Aug 17 '10 at 09:52
  • You could make a dynamic-scoped lisp-1. You don't have to tell them it's lisp. Or if you prefer, you could go get LIME for PHP and implement infix algebra, perhaps inside [square brackets] and make something that looks like TCL. Why does it have to look like PHP? – Ian Aug 17 '10 at 10:58
  • or You can write a parser of a subset of PHP in PHP and run only selected functions! :D – naugtur Aug 17 '10 at 12:04
1

Giving users the possibility to enter PHP code is really dangerous. Consider all other options before implementing this. Some kind of PHP-code builder. Inspired on a Query builder.

If you decide to allow PHP code by the clients, it is better to use a whitelist. You should use regular expressions to extract these functions from the posted code.

Rene Terstegen
  • 7,911
  • 18
  • 52
  • 74
  • 5
    PHP is not a regular language. – Gumbo Aug 17 '10 at 09:09
  • @Gumbo: Please explain what that has to do with this situation? – Rene Terstegen Aug 17 '10 at 09:13
  • 1
    @Stegeman You can't use regular expressions on a language that's not regular. – NullUserException Aug 17 '10 at 09:18
  • Maybe I'm wrong, but he says enter, which, in my understanding, means that he will post the code. In that case the code is just a string and it is possible to use regular expressions on a string isn't it? If he wants to upload the code I know I'm wrong. Just trying to understand and learn a little :) – Rene Terstegen Aug 17 '10 at 09:25
  • 1
    @Stegeman: Sure you can use regular expressions on strings. But the data in the string (i.e. PHP code) is not a regular language. Just think about removing the function call of `foobar` in a PHP code like this: ` – Gumbo Aug 17 '10 at 09:30
  • @Gumbo, thanks for the lesson. +1 for that :) – Rene Terstegen Aug 17 '10 at 09:40
1

What you are expected to do is extremely hard work if you want to get it right. I would start by parsing the entered php code, checking each called function, disallowing backticks altogether, etc.

In other words: If you want to allow a sub-set of PHP you must implement your own lexer (even if PHP provides you a parser out of the box).

soulmerge
  • 73,842
  • 19
  • 118
  • 155