CVE-2025-25200: this Koa ReDoS is not a serious vulnerability
CVE-2025-25200 describes a regex denial of service (ReDoS) in the Koa web framework. While classified as critical, its actual impact is minimal.
The “vulnerability”
An intermediate proxy often adds the user’s IP address and the requested host name to request headers (X-Forwarded-For
, X-Forwarded-Host
). These headers can contain multiple values, separated by commas. Koa splits these headers using an inefficient regular expression, which takes up more processing power than needed for long headers:
get host() {
const proxy = this.app.proxy;
let host = proxy && this.get('X-Forwarded-Host');
// ...
return host.split(/\s*,\s*/, 1)[0];
},
This regex has O(n²) time complexity. This means the time taken to process the input increases quadratically with the input’s length. This can be exploited by sending a request with a X-Forwarded-Host or X-Forwarded-For header with many spaces, allegedly causing the server to be so busy it cannot respond to legitimate requests anymore.
ReDoS
The regular expression \s*,\s*
matches zero or more spaces, a comma, and then again zero or more spaces. The goal is to split on commas and also trim whitespace.
While this regex does not look scary, it indeed is slow with long inputs. With an input of 100KB of spaces, this takes about 5 seconds.
Of course, there is nothing about this regex that makes it inevitably slow. You could imagine a regex engine that first searches for the comma and then matches the surrounding whitespace, instead of getting hung up on all the whitespace. In fact, fast non-backtracking engines exist and are resistant to ReDoS. Unfortunately, most languages and frameworks use a slow engine and can be vulnerable to ReDoS.
Terms and conditions apply
To slow down the Koa app, we need it to parse our malicious input. Sending a malicious input in a header is not sufficient. The header is only parsed under certain conditions.
Only works in proxy mode
As we saw in the code above, the headers are only read if proxy
is set to true, and it is false by default. This setting presumably tells Koa whether a proxy is being used.
If a proxy is used, it is also quite possible that the proxy strips or sanitizes the headers. To prevent spoofing the client’s IP address, it is recommended to delete the client’s X-Forwarded-For
header and set your own value in the proxy. In that case, the application won’t be vulnerable.
Lazy Property Access
The functions that use the slow regex are not called by default. The vulnerability is only triggered if certain context properties are accessed.
- the X-Forwarded-Host header is only parsed when the app reads ctx.host.
- the X-Forwarded-For header is only parsed when the app reads ctx.ip or ctx.ips.
Header Size Limitations
Node.js has a maximum HTTP header size limit of 16KB. This means it is not possible to send larger payloads, which would be required to really make the server take a long time on the regex. A header of 16KB only takes about 200 milliseconds to process. This is not great, but I know websites that take longer to render the homepage, so apparently it is not such a big deal.
Subsequent impact
CVSS v4 is a vulnerability scoring system used to determine the severity of this vulnerability. It has two impact classifications: direct impact and subsequent impact. Direct impact is the consequence for the system that contains the vulnerability. Subsequent impact is the effect on another system. If the web app exposes a password reset token, it has direct confidentiality impact (the token is exposed) and subsequent integrity impact (the password can be changed).
In this case, Koa is vulnerable and Koa is impacted. Even so, this vulnerability is classified as high availability impact, both for direct impact and subsequent impact. I checked 24 other ReDoS CVEs, and none of them have subsequent impact.
Availability impact
CVSS rates confidentiality, integrity and availability impact the same. High confidentiality impact rates the same as high availability impact. I think this can be a valid viewpoint in some cases where there is permanent impact, but not in most other cases.
- High confidentiality impact: the app’s database is dumped and released on a hacker forum. Your company is in the news for being hacked and your business takes a serious hit.
- High integrity impact: hackers add an admin account or encrypt all your files. They replace your homepage with “H@xed by haxors”. Your company is in the news and your business takes a serious hit.
- High availability impact according to CVSS: hackers DDoS your server. You wait it out or put Cloudflare in front, and release a statement that your company was the victim of a DDoS attack. Happens to everyone, nobody blames you.
- High availability impact, actually: hackers delete all your company data. Rebuilding your infrastructure from backups takes weeks. Your company is in the news and your business takes a serious hit.
In this Koa ReDoS, the availability impact is temporary. The server becomes unresponsive for a short period when processing a malicious header. Once the connection times out or the request is completed, the server resumes normal operation. This differs significantly from a permanent denial of service or data loss.
Out of the 24 ReDoS CVEs I looked at, six has high availability impact, and 18 had low availability impact.
Nobody checks CVEs
Rating a ReDoS as 9.8 critical does not make sense in any case. I feel that the reporter was hunting for high-risk CVEs for their resume. When reporting a vulnerability through GitHub, it is possible to enter your own CVSS score, and apparently the reporter made the most out of this. Both GitHub and NVD apparently did not perform basic checking of the CVSS score.
Should ReDoS be taken seriously?
I am skeptical of ReDoS. I don’t consider it an actual risk. I started looking into this CVE to learn about how serious ReDoS could be. I thought a critical CVE would show the real impact of this vulnerability class. Instead it showed that an attacker can make a request take 200ms in very specific conditions. It also showed that security researchers, CVSS, and CVE authorities cannot be trusted to correctly classify a vulnerability.
If you have an example of an actually dangerously ReDoS, please email me.
Conclusion
The Koa ReDoS can only be exploited when:
- the app enables proxy mode,
- reads the host, ip or ips properties,
- the intermediate proxy does not strip or sanitize the headers.
Even then, a request can take in the order of 200 milliseconds, which is not really that much. So this is not a serious vulnerability, and the 9.2 / Critical seems inflated. A more reasonable scoring would be CVSS 6.3 / Medium, based on attack requirements and low availability impact.
I feel like a security researcher wanted to have a high-risk CVE on his name, and didn’t care about how many headaches that caused for developers and sysadmins, who felt they had to fix this vulnerability immediately.
Read more
- Increase HTTP_MAX_HEADER_SIZE to 16kb · Issue #27645 · nodejs/node
- Inefficient Regular Expression Complexity in koa · Advisory · koajs/koa
Other ReDoS CVEs
- CVE Record: CVE-2024-47888
- CVE Record: CVE-2024-47889
- CVE Record: CVE-2024-49761
- CVE Record: CVE-2024-52524
- CVE Record: CVE-2024-52798
- CVE Record: CVE-2024-9277
- CVE Record: CVE-2025-2811
- CVE Record: CVE-2025-2833
- CVE Record: CVE-2025-3985
- CVE Record: CVE-2025-3986
- CVE Record: CVE-2025-4215
- CVE Record: CVE-2025-4727
- CVE Record: CVE-2025-48058
- CVE Record: CVE-2025-48059
- CVE Record: CVE-2025-49007
- CVE Record: CVE-2025-5889
- CVE Record: CVE-2025-5890
- CVE Record: CVE-2025-5891
- CVE Record: CVE-2025-5892
- CVE Record: CVE-2025-5895
- CVE Record: CVE-2025-5896
- CVE Record: CVE-2025-5897
- CVE Record: CVE-2025-6492
- CVE Record: CVE-2025-6493