---
title: "Keep regular expressions from stalling the · Agent Wranglers"
url: https://agentwranglers.se/playbook/application-security/limits-and-business-logic/regex-denial-of-service
id: APS-51
level: Required
risk: outage
updated: 2026-10-27
build: a2a6bdfed830
tokens: 1031
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Keep regular expressions from stalling the server

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Limits and business logic](https://agentwranglers.se/playbook/application-security/limits-and-business-logic.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: APS-51
- Level: Required
- Chapter: [Limits and business logic](https://agentwranglers.se/playbook/application-security/limits-and-business-logic.md)
- Rule: Match untrusted input only with a linear-time regular expression engine, or cap the input length before a backtracking engine reads it. Never build a pattern from user input.
- Check: On the test copy, send every field that a pattern checks 50,000 copies of `a` followed by `!`. Each answer arrives within 1 second. A small page fetched at the same time passes [Prove one request cannot stall the site](https://agentwranglers.se/playbook/testing/performance-tests/single-request-stall.md). A search of the code finds no pattern built from request data.
- Risk: The app down or unusable
- How: A backtracking engine can spend minutes on a short crafted string when a pattern nests repetition, such as `(a+)+$` or `([a-zA-Z]+)*$`. OWASP calls these evil patterns. In Node.js one such match blocks every other request, because the server runs your code on one thread. Go's `regexp` package guarantees time linear in the input, and RE2 bindings exist for most languages. .NET takes a match timeout and offers a non-backtracking option. Where you keep a backtracking engine, cap the input first, as [Cap the size of every request and answer](https://agentwranglers.se/playbook/api-design/requests-and-responses/request-body-limit.md) says. Remove nested quantifiers, and escape any user text that must go into a pattern. A linter rule, such as `regexp/no-super-linear-backtracking` in ESLint, finds many evil patterns in CI.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
import RE2 from 're2';

const MAX_SLUG_LENGTH = 100;
const SLUG = new RE2('^[a-z0-9]+(?:-[a-z0-9]+)*$');

export const isSlug = value => value.length <= MAX_SLUG_LENGTH && SLUG.test(value);
```

### Python example

```python
import re

MAX_SLUG_LENGTH = 100
SLUG = re.compile(r"[a-z0-9]+(?:-[a-z0-9]+)*")

def is_slug(value: str) -> bool:
    return len(value) <= MAX_SLUG_LENGTH and SLUG.fullmatch(value) is not None
```

## Sources

- [OWASP on regular expression denial of service](https://community.owasp.org/attacks/Regular_expression_Denial_of_Service_-_ReDoS)
- [CWE-1333 Inefficient Regular Expression Complexity](https://cwe.mitre.org/data/definitions/1333.html)
- [Go regexp package](https://pkg.go.dev/regexp)

## Related rules

- API-93 [Cap the size of every request body](https://agentwranglers.se/playbook/api-design/requests-and-responses/request-body-limit.md) in API design
- TST-54 [Prove one request cannot stall the site](https://agentwranglers.se/playbook/testing/performance-tests/single-request-stall.md) in Testing

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/application-security/limits-and-business-logic/regex-denial-of-service">Agent Wranglers application security playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Take the client address only from proxies you run](https://agentwranglers.se/playbook/application-security/limits-and-business-logic/trusted-proxy-client-address.md)
- Next: [Work out every amount on the server](https://agentwranglers.se/playbook/application-security/limits-and-business-logic/server-side-business-rules.md)
- [Limits and business logic](https://agentwranglers.se/playbook/application-security/limits-and-business-logic.md)
