CWE-624, Executable Regular Expression Error, covers two cases: a regular expression with an executable component that user input can reach, and a pattern where a user can enable execution by inserting modifiers. MITRE lists PHP and Perl as the platforms.
How it happens
In PHP's preg_replace(), the e modifier made the replacement string run as PHP code. If user input lands in the pattern string, an attacker can add that modifier. MITRE notes this is possible in preg_replace() and possibly in other languages when user-controlled input is inserted into a string later parsed as a regular expression.
// Vulnerable: user text becomes part of the pattern
$pattern = '/' . $_GET['q'] . '/e';
preg_replace($pattern, $_GET['r'], $text);
The observed CVEs are all PHP: inserting the e modifier into the first argument of preg_replace (CVE-2006-2059), complex curly syntax in the replacement of a /e call, and a username field that reached a preg_replace with an executable modifier.
What an attacker gains
The consequence is unauthorized code or command execution, affecting confidentiality, integrity and availability.
How to find it
Static analysis (SAST) can find some instances by modeling data flow from input to regex calls. A manual search helps too: look for preg_replace with an e modifier and for any pattern built by concatenating request data.
How to fix it
MITRE's mitigation: use the regex feature that lets inputs be quoted or escaped before insertion, such as \Q and \E in Perl. In PHP, preg_quote() serves the same purpose for escaping user text, and replacing /e with preg_replace_callback avoids executable replacement entirely. Both are standard practice beyond the MITRE record.
$safe = preg_quote($_GET['q'], '/');
$pattern = '/' . $safe . '/';
A closer look at case two
The second case in the definition is easy to miss. The regular expression itself may be fine, but a user can insert pattern modifiers that switch on execution. If user input forms part of the pattern string, the modifier suffix is only a few characters away.
This is also why the weakness sits next to injection problems. The user supplies data, the program treats it as code. Quoting the input, as the Perl \Q and \E markers do, tells the regex engine that the text is literal.
The same reasoning applies to the replacement argument. One of MITRE's examples used the complex curly syntax in the replacement string of a /e call, which is another path for user text to become executable.
If you maintain legacy PHP, a quick audit is to search for the e modifier in every preg_replace call and review each one by hand.
Review checklist:
- Find every
preg_replaceand similar call that builds a pattern from variables. - Check whether the pattern or the replacement can include user text.
- Quote user text before it enters a pattern.
- Remove executable modifiers from anything an outsider can influence.
These steps are quick on a small codebase and are worth running whenever you take over old PHP or Perl scripts.
Quick check
What did the e modifier do?
It treated the replacement as code to execute, so an attacker who could add it could run PHP code.