Regular Expression That Can Run Forever
A regular expression can take exponential time on a crafted input, or is built from input the caller controls.
Why it matters
Python's re module backtracks. When a repeated group contains another repeat, the number of ways to match grows with the input, and a string of a few dozen characters that almost matches keeps the worker busy for a long time. One request is enough to block a Flask or FastAPI worker.
What it looks like
This is the shape of code that triggers the rule. AI tools produce it because it works, and nothing tells them it is unsafe.
EMAIL = re.compile(r"^([a-zA-Z0-9_.+-]+)+@(\w+)+\.com$")The smallest fix
# Before
EMAIL = re.compile(r"^([a-zA-Z0-9_.+-]+)+@(\w+\.)+\w+$")
# After: one way to match each character, plus a length cap
EMAIL = re.compile(r"^[a-zA-Z0-9_.+-]{1,64}@[a-zA-Z0-9-]{1,63}(?:\.[a-zA-Z0-9-]{1,63})+$")
if len(value) > 254: abort(400)The better fix
If you have a few more minutes, this is the approach that holds up as the app grows.
# Use a validator (email-validator, pydantic's EmailStr) instead of a
# hand-written pattern, and never compile a pattern from request data
# without re.escape().Let your AI tool fix it
When the scanner finds this in your project, it fills in the file and line for you. This is the prompt it gives you to paste into Claude Code, Cursor or whatever you use.
How to check the fix worked
1. Time the regex against 30 characters that almost match; it must return in under a millisecond. 2. Confirm valid inputs still match and invalid ones still fail.