php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #48180 mb_ereg(i)_replace() evaluate replacement string not escaped properly
Submitted: 2009-05-07 14:54 UTC Modified: 2009-05-10 21:29 UTC
From: 5up3rh3i at gmail dot com Assigned: fa (profile)
Status: Closed Package: Documentation problem
PHP Version: 5.*CVS, 6CVS (2009-05-08) OS: *
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
12 + 48 = ?
Subscribe to this entry?

 
 [2009-05-07 14:54 UTC] 5up3rh3i at gmail dot com
Description:
------------
when option parameter set e, matches not be escaped.

ex:

<?php

function 80vul() {}

$str = '\', phpinfo(), \'';
mb_ereg_replace('^(.*)$', '80vul(\'\1\')', $str, 'e');

?>

phpinfo() will be evaluated.

mb_ereg_replace()

				if ((replace_len - i) >= 2 && fwd == 1 &&
					p[0] == '\\' && p[1] >= '0' && p[1] <= '9') {
					n = p[1] - '0';
				}
				if (n >= 0 && n < regs->num_regs) {
					if (regs->beg[n] >= 0 && regs->beg[n] < regs->end[n] && regs->end[n] <= string_len) {
						smart_str_appendl(pbuf, string + regs->beg[n], regs->end[n] - regs->beg[n]);
// matches not be escaped
					}
					
preg_replace()

		if ('\\' == *walk || '$' == *walk) {
			smart_str_appendl(&code, segment, walk - segment);
			if (walk_last == '\\') {
				code.c[code.len-1] = *walk++;
				segment = walk;
				walk_last = 0;
				continue;
			}
			segment = walk;
			if (preg_get_backref(&walk, &backref)) {
				if (backref < count) {
					/* Find the corresponding string match and substitute it
					   in instead of the backref */
					match = subject + offsets[backref<<1];
					match_len = offsets[(backref<<1)+1] - offsets[backref<<1];
					if (match_len) {
						esc_match = php_addslashes_ex(match, match_len, &esc_match_len, 0, 1 TSRMLS_CC);
// matches escaped by addslashes()
...
				smart_str_appendl(&code, esc_match, esc_match_len);


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-05-09 05:13 UTC] jani@php.net
This should show the problem more clearly:

<?php

function test() {echo "THIS SHOULD NOT BE SEEN!!\n";}
function ryat($a) {var_dump($a);}

$str = "', test(), '";

echo "mb_ereg_replace()\n";
var_dump(mb_ereg_replace('^(.*)$', "ryat('\\1')", $str, 'e'));

echo "\npreg_replace()\n";
var_dump(preg_replace('/^(.*)$/e', "ryat('\\1')", $str));

?>

 [2009-05-09 05:41 UTC] jani@php.net
Considered and realized that we can't really fix this. You just have to 
do the 'addslashes()' yourself. Reason: doing "magical" addslashes() 
call on the replacement would cause problems with certain encodings.
 [2009-05-10 20:11 UTC] jani@php.net
This has to be documented of course. Using these "eval" parameters is 
inherently bad idea..
 [2009-05-10 21:29 UTC] fa@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat May 04 21:01:32 2024 UTC