ReDoS

You sanitized your input fields for XSS? You might have opened a new door for attackers…
Imagine this: You’re a developer at your company. After a penetration test, several issues were found in your app, some input fields have no limits on length or content. This leaves your app open to threats like XSS. You need to fix these issues as soon as possible.
What’s the first thing that comes to mind? Maybe you decide to use regular expressions (regex) to keep things under control. It seems like a good plan… or maybe it’s not.
The Issue: Using a Regex to Verify Length
Normally, if you don’t want an input to exceed, say, 200 characters, you’d just measure its length. It’s quick, straightforward, and efficient. But here, the developers chose a regex like:
^.{0,200}$
This pattern checks if a string is between 0 and 200 characters. The problem? The regex engine has to analyze the entire input, regardless of how huge it might be.
The Attack: An Overwhelmingly Long String
To test this vulnerability, I decided to go all out. Instead of 1,000 or even 10,000 characters, I tried sending a massive 20 million characters. My goal was simple: overload the server so the regex engine would devour an enormous amount of resources.
I wrote a quick Python script to launch the attack:
import requests
payload = "A" * 20000000 # 20 million characters
response = requests.post("https://vulnerable-app.com/endpoint", data={"input_field": payload})
print(response.status_code)
As soon as I ran it, the server began to struggle under the weight of all that data. The regex engine got stuck handling the giant string. Within minutes, the server was overwhelmed and completely crashed, locking everyone out of the site.
This simple yet devastating tactic showed how a poorly chosen regex can turn a basic input check into a serious security hole, giving attackers a way to knock the entire site offline with minimal effort.
The Real Solution: Limit Input Size Directly
The real issue is that the server tries to process the entire string. The best fix? Don’t let it get that far. The moment you receive the input, trim it to the first 200 characters—no regex needed. For example:
Examples:
// Node.js
const input = req.body.input_field || "";
const inputClean = input.substring(0, 200);
# Python
user_input = request.get("input_field", "")
input_clean = user_input[:200]
That way, no matter how huge the incoming data is, the server only deals with the first 200 characters. It’s a simple and effective method that prevents a dangerous denial of service scenario caused by a naive regex approach.