I'm currently improving my knowledge about security holes in HTML, PHP, JavaScript etc.
A few hours ago, I stumbled across the /e
modifier in regular expressions and I still don't get how it works. I've taken a look at the documentation, but that didn't really help.
What I understood is that this modifier can be manipulated to give someone the opportunity to execute PHP code in (for example, preg_replace()
). I've seen the following example describing a security hole but it wasn't explained, so could someone please explain me how to call phpinfo()
in the following code?
$input = htmlentities("");
if (strpos($input, 'bla'))
{
echo preg_replace("/" .$input ."/", $input ."<img src='".$input.".png'>", "bla");
}
e
Regex Modifier in PHP with example vulnerability & alternativesWhat e
does, with an example...
The e
modifier is a deprecated regex modifier which allows you to use PHP code within your regular expression. This means that whatever you parse in will be evaluated as a part of your program.
For example, we can use something like this:
$input = "Bet you want a BMW.";
echo preg_replace("/([a-z]*)/e", "strtoupper('\\1')", $input);
This will output BET YOU WANT A BMW.
Without the e
modifier, we get this very different output:
strtoupper('')Bstrtoupper('et')strtoupper('') strtoupper('you')strtoupper('') strtoupper('want')strtoupper('') strtoupper('a')strtoupper('') strtoupper('')Bstrtoupper('')Mstrtoupper('')Wstrtoupper('').strtoupper('')
Potential security issues with e
...
The e
modifier is deprecated for security reasons. Here's an example of an issue you can run into very easily with e
:
$password = 'secret';
...
$input = $_GET['input'];
echo preg_replace('|^(.*)$|e', '"\1"', $input);
If I submit my input as "$password"
, the output to this function will be secret
. It's very easy, therefore, for me to access session variables, all variables being used on the back-end and even take deeper levels of control over your application (eval('cat /etc/passwd');
?) through this simple piece of poorly written code.
Like the similarly deprecated mysql
libraries, this doesn't mean that you cannot write code which is not subject to vulnerability using e
, just that it's more difficult to do so.
What you should use instead...
You should use preg_replace_callback in nearly all places you would consider using the e
modifier. The code is definitely not as brief in this case but don't let that fool you -- it's twice as fast:
$input = "Bet you want a BMW.";
echo preg_replace_callback(
"/([a-z]*)/",
function($matches){
foreach($matches as $match){
return strtoupper($match);
}
},
$input
);
On performance, there's no reason to use e
...
Unlike the mysql
libraries (which were also deprecated for security purposes), e
is not quicker than its alternatives for most operations. For the example given, it's twice as slow: preg_replace_callback (0.14 sec for 50,000 operations) vs e modifier (0.32 sec for 50,000 operations)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With