Safeguard
Application Security•

CWE-624 Executable Regular Expression Error in PHP and Perl

A regex that can execute code, or lets a user switch execution on, turns a text match into remote code execution. Quote user input before it enters a pattern.

Safeguard Security Team
3 min read

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_replace and 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.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.