RE: [PHP4BETA] Dangerous PCRE security error
| From: | Samuel Liddicott | Date: | Mon, 18 Oct 1999 15:45:33 +0000 |
| Subject: | RE: [PHP4BETA] Dangerous PCRE security error | ||
| References: | 1 | Groups: | php.version4 |
| Request: | Send a blank email to php-version4+get-5550@lists.php.net to get a copy of this message | ||
> -----Original Message-----
> From: Andrei Zmievski [mailto:andrei@ispi.net]
> Sent: Friday, October 15, 1999 06:26 PM
> To: Samuel Liddicott
> Cc: php4beta@lists.php.net
> Subject: Re: [PHP4BETA] Dangerous PCRE security error
>
>
> On Thu, 14 Oct 1999, Samuel Liddicott wrote:
> > It seems like the /e modifier of preg_replace is directly
> equivalent to eval
> > (fair enough) but without any safety features.
>
> You're right in assuming that /e is equivalent to eval(). But
> tell me, what security features does eval() have?
PHP eval? None, but it doesn't need it as such because you can AddSlashes()
and other stuff before you do the eval.
Here, you don't have a chance.
> > Take this simplified case:
> >
> > $newlines=preg_replace('/^((| *[^ ]* *=) *(def[^\(]*).*\);.*$)/e',
> >
> > 'GetDebugLine('."'".'\\1'."'".')',
> > $lines);
> >
> > and where $lines[1] actually contains:
> > defmenuopt(e, 0, "Check", '\2');
>
> Don't you mean \3?
No, I was writing some non-web-related php scripts to add debuging
fprintf(stderr lines before and after certain C statements...
> > The replace eval string gets constructed as:
> > GetDebugLine(' defmenuopt(e, 0, "Check", '\2');')
> >
> > Which is shamefully invalid, and if such preg_replace are done on user
> > supplied data, watch:
>
> Why is it invalid?
look: GetDebugLine( [' defmenuopt(e, 0, "Check", '] [\2] [');'] )
Thats not valid code, so its invalid. My point was, if some escaping was
possible, it might be made valid by use of AddSlashes...
> > I this line is passed:
> > defmenuopt(e, 0, "Check", '.unlink("/linux/boot").');
> >
> > the eval string becomes:
> > GetDebugLine(' defmenuopt(e, 0, "Check",
> > '.unlink("/linux/boot").');')
> >
> > which would be pretty nasty.
>
> > Maybe there needs to be a modifier to cause the \\1-\\99 tokens
> to be quoted
> > the correct way for being enclosed in " ". (add \ to all \ and ") or '
> > '
> > (replace all ' with '."'".')
>
> I don't see /e doing anything wrong. If you pass in a string with
> unlink() in it, well, then it is going to get evaluated. It has
> nothing to do with \\1-\\99 tokens.
No. Look, this text (mere text) is passed to a pcre for matching:
defmenuopt(e, 0, "Check", '.unlink("/linux/boot").');
and then I want to eval some PHP to calculate the replacement. That is what
/e is for. There is NO WAY to stop the matched text become eval'ed in a
context other than paramter to function. Carefully crafted user-supplied
text could be written to cause the php to do things other than what the
designer wanted. The example shows the program matching on a string that
contains an some words including unlink, yet it is impossible to pass this
safely as a parameter to the GetDebugLine() /e function.
AddSlashes and EscapeShellCmd all admit this need in their various scopes, I
think we need one for PCRE /e
Sam