October 16, 2026
$6,500 for a Regex That Couldnβt Say No: ReDoS in an Email Validation Field
Most denial-of-service findings in bug bounty programs get an immediate, reasonable skepticism from triage, because flooding an endpointβ¦

By T4nv1
7 min read
Most denial-of-service findings in bug bounty programs get an immediate, reasonable skepticism from triage, because flooding an endpoint with traffic isn't usually an interesting vulnerability β it's just traffic, and most programs explicitly exclude volumetric DoS from scope entirely. This bug was different in kind, not degree: a single request, a few hundred bytes long, capable of pinning one CPU core at 100% for minutes at a time, with no amplification, no botnet, no volume required at all. That distinction β one request, not many β is what makes regular expression denial of service worth taking seriously as an actual vulnerability class rather than dismissing alongside ordinary flood-based DoS.
The target, which I'll call Thorncastle here per their program's disclosure terms, is a newsletter and email-marketing platform, with the obvious, heavily-used attack surface for this bug class sitting right at the front door: email address validation, present on practically every form across the product.
Why Some Regular Expressions Can Take Exponential Time
Regular expression engines, for a specific and well-understood category of pattern, can exhibit catastrophic backtracking β a worst-case time complexity that grows exponentially with input length, rather than linearly, for certain crafted inputs that nearly match the pattern but ultimately fail. This happens specifically with patterns containing nested or overlapping quantifiers, where the engine has many different ways to partition the same input string across the pattern's repeated groups, and when the overall match ultimately fails, it ends up trying an exponential number of those partitionings before giving up entirely, one by one, through backtracking.
A classic, simplified example of the vulnerable shape:
^([a-zA-Z0-9]+)+$^([a-zA-Z0-9]+)+$The outer (...)+ and inner [a-zA-Z0-9]+ both independently try to consume as much of the input as possible, and critically, there are many different ways to split a run of matching characters between the inner and outer repetition that all produce the same overall match β meaning when a final character forces the whole match to fail, the engine has an enormous number of equivalent-looking partitionings left to exhaustively try before concluding failure, and that number grows exponentially with the length of the matching run.
Finding the Vulnerable Pattern
I didn't have source access to Thorncastle's actual validation regex, so confirming this required inferring the pattern's likely shape from behavior rather than reading it directly. Email-validation patterns are notorious for this specific vulnerability class, because a genuinely correct, fully RFC-compliant email regex is notoriously complex, and a lot of real-world implementations copy a plausible-looking but subtly dangerous pattern from an old Stack Overflow answer or tutorial without understanding its backtracking behavior under adversarial input.
I started with a baseline timing test, submitting a normal, valid email address to the newsletter signup form and measuring response time β consistently fast, well under 100 milliseconds. Then I tested a deliberately crafted input designed to trigger catastrophic backtracking in the kind of nested-quantifier pattern commonly used for validating the "local part" of an email address before the @ symbol β a long run of characters that would almost, but not quite, satisfy a vulnerable pattern's structure, followed by a single character guaranteed to force the overall match to fail only after the engine had already committed to extensive backtracking:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!@example.comaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!@example.comThirty-some repeated characters, followed by an exclamation mark the pattern wouldn't accept, followed by a syntactically normal domain. Submitted to the signup form's email field, the response took roughly four seconds to return β dramatically slower than the baseline, and a strong signal the server-side validation regex was exhibiting exactly the kind of backtracking blowup this input was designed to trigger.
Measuring the Actual Blowup Curve
A single slow response is suggestive but not yet a complete, convincing finding β the real severity question is how the response time scales as the crafted input grows, because catastrophic backtracking's defining signature is genuinely exponential growth, not merely "somewhat slower than usual." I ran the same test pattern at several increasing lengths of the repeated character run, holding everything else constant, and recorded response times:
25 characters: ~0.8 seconds
30 characters: ~3.1 seconds
35 characters: ~11.4 seconds
40 characters: ~47.2 seconds (request timed out server-side before full completion)25 characters: ~0.8 seconds
30 characters: ~3.1 seconds
35 characters: ~11.4 seconds
40 characters: ~47.2 seconds (request timed out server-side before full completion)That curve β each additional five characters roughly multiplying the response time by a factor of three to four, rather than adding a fixed increment β is unmistakably exponential growth, not a linear slowdown from heavier processing. It confirmed this wasn't just "validation is a bit slow for weird input." It was a genuine algorithmic blowup, where an attacker could extend the input by a handful of characters at a time and watch processing cost roughly quadruple with each extension, eventually pinning a server-side process at full CPU utilization for far longer than any legitimate request should ever take, from a single, tiny HTTP request costing the attacker essentially nothing to send.
Why a Single Request Mattering Is the Whole Point
It's worth being explicit in a report about why this specific vulnerability class deserves to be treated differently from ordinary, excluded-by-policy volumetric DoS, since triage teams reasonably see a lot of low-value DoS submissions and may initially categorize this the same way without looking closely. The distinguishing fact is that a single, small request β not a flood, not coordinated traffic from many sources, nothing resembling what a WAF or rate limiter is designed to catch β can consume a disproportionate, exponentially scaling amount of server-side compute. Multiple such requests sent in parallel, each cheap to construct and send, could plausibly exhaust available worker processes or threads handling form submissions platform-wide, denying service to legitimate users without needing anything resembling a traditional DoS attack's volume or infrastructure at all.
Keeping the Demonstration Responsible
I capped my testing at the input lengths shown above, specifically stopping before reaching lengths likely to cause request timeouts that might meaningfully degrade service for other users sharing the same infrastructure during my testing window. I did not send concurrent requests to amplify the effect, and I did not test this against any endpoint beyond the single signup form where I'd confirmed the vulnerable pattern, even though the same regex was plausibly reused elsewhere across the platform's many other email-collecting forms.
The Report
ReDoS reports need to work harder than most to establish legitimacy, precisely because of how much low-value DoS noise most triage teams have seen β leading with the exponential timing curve, not just a single slow response, is what separates a credible finding from something that reads like ordinary network-level flooding.
Title: Regular expression denial of service (ReDoS) in email validation allows single-request CPU exhaustion via catastrophic backtracking
Root cause: The server-side email validation pattern contains nested or overlapping quantifiers vulnerable to catastrophic backtracking, causing processing time to grow exponentially with specially crafted input length. A single, small HTTP request can trigger response times scaling from under a second to tens of seconds or beyond with only minor increases in a crafted input string's length.
Reproduction: The baseline timing measurement, the crafted payload structure, and the full table of response times across increasing input lengths, demonstrating clearly exponential rather than linear growth, with explicit confirmation that testing was deliberately capped below lengths likely to cause broader service impact and was not repeated concurrently.
Impact: Any unauthenticated user can send a single, small request causing disproportionate server-side CPU consumption; repeated or parallel submissions of similarly crafted inputs could plausibly exhaust available request-handling capacity platform-wide, denying service to legitimate users, without requiring any volumetric attack infrastructure.
Fix recommendations:
- Replace the vulnerable regex pattern with one that avoids nested or ambiguous quantifiers, or adopt a well-tested, published email-validation pattern specifically vetted against catastrophic backtracking
- Enforce a maximum input length on the email field well before validation runs, which bounds the worst-case processing time regardless of the pattern's own safety
- Apply a hard execution timeout to regex evaluation itself at the application or runtime level, so that even an unknown future vulnerable pattern elsewhere in the codebase can't cause unbounded processing time
- Audit other input-validation patterns across the platform for the same nested-quantifier structure, since a regex copied from the same source is often reused unmodified across multiple unrelated forms
What Happened After
Thorncastle replaced the vulnerable pattern with a safer, bounded alternative within five days, and added an input length cap as an additional, independent safeguard shortly after. Their resolution notes mentioned finding the same vulnerable pattern reused on two other forms elsewhere in the platform, both fixed in the same pass. The report closed at $6,500, rated medium-to-high severity, reflecting genuine single-request resource exhaustion potential weighed against the fact that full platform-wide impact would require some degree of request parallelization beyond the single-request proof of concept itself.
Why ReDoS Deserves a Place in Your Testing Routine
This bug class rewards a specific kind of suspicion toward any input-validation field handling even moderately complex patterns β anywhere a regex is doing real structural validation (email addresses, URLs, phone numbers with extensions, complex password rules) is worth testing for backtracking blowup, because the underlying mistake is easy to make and genuinely hard to notice without deliberately crafted adversarial input. A few habits worth carrying forward:
Always measure a timing curve across increasing input lengths, not just a single slow response. The distinguishing signature of real catastrophic backtracking is exponential, not linear, growth β and demonstrating that curve clearly is what makes a ReDoS report credible rather than dismissible as noise.
Email validation, URL validation, and any pattern involving nested repetition are the highest-value targets. These are exactly the kinds of patterns developers are most likely to copy from an unvetted source without understanding their worst-case behavior.
Cap your own testing well before causing genuine service degradation. The exponential nature of this bug class means testing can spiral into real impact faster than intended β stopping at a input length that clearly demonstrates the pattern, without pushing toward actual service-wide disruption, is both the responsible approach and usually sufficient for a complete report.
Make the exponential-growth case explicit and data-driven in the report itself. A triager who's seen a hundred low-value DoS submissions needs to see the curve, not just be told "this is slow," to correctly distinguish a genuine algorithmic vulnerability from ordinary noise.
What I keep coming back to with this one is how small the actual trigger was. Thirty-some characters and a symbol, sent once, no special tooling, no infrastructure, no coordination β and a server-side process pinned at full CPU for the better part of a minute. The entire vulnerability class exists in that gap between how little an attacker has to do and how disproportionately expensive the resulting computation becomes, hiding inside a pattern most people assume is simple precisely because, most of the time, on most input, it runs instantly.