PHP preg_replace used on user input
Description
This application uses the PHP preg_replace() function with user-controlled input. When the deprecated /e modifier is used, preg_replace() evaluates the replacement parameter as PHP code after performing pattern substitution. If an attacker can control either the regex pattern or the replacement string, they may be able to inject and execute arbitrary PHP code on the server.
Remediation
Take the following steps to remediate this vulnerability:
1. Remove the /e modifier and use preg_replace_callback() instead:
The /e modifier has been deprecated since PHP 5.5.0 and removed in PHP 7.0.0. Replace preg_replace() calls with preg_replace_callback():
// Vulnerable code:
$result = preg_replace('/(\w+)/e', 'strtoupper("$1")', $input);
// Secure alternative:
$result = preg_replace_callback('/(\w+)/', function($matches) {
return strtoupper($matches[1]);
}, $input);
2. Validate and sanitize all user input:
Never allow user input to directly control regex patterns or replacement strings. If user input must be included, apply strict validation and use preg_quote() to escape special regex characters:
// Escape user input used in patterns
$safe_pattern = preg_quote($user_input, '/');
$result = preg_replace('/' . $safe_pattern . '/', $replacement, $subject);
3. Upgrade PHP version:
Ensure you are running PHP 7.0 or later, where the /e modifier is no longer supported, preventing this class of vulnerability.
4. Conduct a code review:
Search your codebase for all instances of preg_replace() and verify that none use the /e modifier or accept unsanitized user input in pattern or replacement parameters.