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
 [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: Thu Apr 25 15:01:30 2024 UTC