I found a more evil example: <?php $a = "___! `rm -rf /tmp/sess_*` !___"; $b = preg_replace("/!(.*)!/e", "print(\\1);", $a); ?>
This happily executes "rm -rf /tmp/sess_*". I will not give out more examples, but if one examines the code for addslashes() it is quite obvious what you can an cannot do here. Thus it is clearly a Bad Thing for someone to use preg_replace with the /e modifier and not use quotes around the \\n or $n backrefs. The docs should be updated to include a very noticeable warning about this hole. I am contemplating possible solutions for this problem... Also as a side note, it does not seem to be possible to use 'echo' as part of the expression, print must be used. (Yes I know why, just pointing it out.) -James On Thu, 30 Jan 2003, James E. Flemer wrote: > Can someone explain what is going on here: > > --- foo.php --- > <?php > $a = "___! 52); echo(42 !___"; > $b = preg_replace("/!(.*)!/e", "print(\\1);", $a); > print("\n---\na: $a\nb: $b\n"); > ?> > --- end --- > --- output --- > 52 > --- > a: ___! 52); echo(42 !___ > b: ___1___ > --- end --- > > I understand that one is supposed to use single quotes > around the \\1 in the above preg_replace. But what happens > when they do not? Clearly the echo(42); is not executed, > and it is not printed by print(). Even more interesting is > if you put something like echo(\"42 in $a, then you get a > bunch of errors including: > Fatal error - Failed evaluating code: > print( 52); echo(\"42 ); > > It seems like preg_replace() is doing some strange things, > and might be something that could be exploitable if a > remote user can supply the first argument, and the second > argument does not enclose \\n options. > > -James > > > -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php