When the User Supplies the Regex: One Line That Took the API Down
Who would have thought an innocent regular expression could bring a system down?
In a system I tested recently I ran into a weakness that looks harmless but in practice opened the door to code injection. The application had an advanced search field, designed to let users filter data using a regular expression. The user would send a payload like this:
POST /api/search
{
"regex": "^[A-Z]{3}[0-9]{4}$"
}
The server-side code used new Regex(userInput) directly to run the expression against the database. The problem is that no validation whatsoever was performed on the expression coming in.
What an attacker sends instead
A malicious regex that causes catastrophic backtracking:
^(a+)+$
and then a relatively short string such as aaaaaaaaaaaaaaaaaaaaaaaa!, which makes the regex engine stall and burn CPU for long seconds. When the attacker sent several of those requests in parallel, every worker thread locked up and the whole API stopped responding. In practice this is a classic ReDoS – denial of service through regular expressions.
To understand the consequences, picture it in production at peak: dozens of users connected, sending business-critical requests. One attacker fires an innocent-looking regex, and a second later the server jumps to 100% CPU. Legitimate calls back up in the queue, reports do not go out, transactions do not complete. Support teams are flooded with complaints, the dashboards go red, and the whole system falls over. What looked like a negligible bug in the code became a total outage in a moment.
What makes it dangerous is that it all looks like a legitimate feature
We developers like giving users flexibility, especially when they want a dynamic search feature. But without thinking about the consequences, the system was given the ability to run a regular expression that arrives directly from the user, on a production server.
How to solve it
- Do not let the user supply a raw regular expression. Give them a set of predefined filters, or a safe DSL.
- If you must support free-form regex, run it inside an isolated sandbox with a hard timeout.
- Use non-backtracking algorithms such as RE2, or similar libraries that do not permit catastrophic backtracking.
- Monitor for unusual use, and identify repeated requests carrying suspicious expressions.
This is a case that demonstrates, again, how legitimate use of a language or library feature becomes a weapon in an attacker’s hands. You do not need SQL injection to bring a system down – a single line of code that accepts a regex from the user, without thinking about what happens beneath the surface, is enough.
Related: the other direction of the same problem – a regex you wrote yourself, for input validation, turning into the denial of service.
I first shared a version of this as a LinkedIn post on 2025-09-22. It is republished here, lightly edited, so it is easier to find and reference. — Erez Metula
