ReDoS Vulnerability Analysis and Fixes
Overview
This document details the analysis and fixes for Regular Expression Denial of Service (ReDoS) vulnerabilities found in the Meteor project's meteor-babel package.
Vulnerabilities Identified
Vulnerability 1: Whitespace Pattern
Location: npm-packages/meteor-babel/test/mocha.js:5949
Original Pattern: /\s+\}$/
Context: .replace(/\s+\}$/, '');
Attack Vectors:
""+" ".repeat(100000)+"◎"""+" ".repeat(100000)+"!"
Problem: The pattern /\s+\}$/ causes catastrophic backtracking when input contains many whitespace characters followed by a non-} character at the end.
Vulnerability 2: Number Pattern
Location: npm-packages/meteor-babel/test/mocha.js:6005
Original Pattern: /(\d+\.\d+)/gm
Context: .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
Attack Vectors:
""+"0".repeat(100000)+"."""+"1".repeat(100000)+"◎"
Problem: The pattern /(\d+\.\d+)/gm causes excessive backtracking when input contains many digits followed by a dot but no digits after.
Fixes Using Negative Lookahead
Fix 1: Whitespace Pattern
// Original (vulnerable)
.replace(/\s+\}$/, '');
// Fixed using positive lookahead
.replace(/\s+(?=\}$)/, '');
Explanation: The positive lookahead (?=\}$) ensures we only match whitespace that is immediately followed by } at the end, preventing backtracking on non-matching endings.
Fix 2: Number Pattern
// Original (vulnerable)
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
// Fixed using negative lookahead
.replace(/(\d+\.\d+)(?!\d)/gm, '<span class="number">$1</span>')
Explanation: The negative lookahead (?!\d) ensures we don't match if there's another digit after the decimal number, making the pattern more precise and preventing backtracking.
Security Impact
- Severity: Medium
- Attack Vector: Malicious input strings
- Impact: CPU exhaustion, application freeze, denial of service
- Affected Component: Test files (potential risk if patterns used in production)
Testing the Fixes
Before Fix (Vulnerable)
// This will cause high CPU usage
const maliciousInput = " ".repeat(100000) + "◎";
const result = maliciousInput.replace(/\s+\}$/, '');
After Fix (Safe)
// This executes quickly
const maliciousInput = " ".repeat(100000) + "◎";
const result = maliciousInput.replace(/\s+(?=\}$)/, '');
Recommendations
- Immediate: Apply the proposed fixes to prevent ReDoS attacks
- Long-term: Implement regex security scanning in CI/CD pipeline
- Best Practice: Use tools like
safe-regexto detect vulnerable patterns - Code Review: Include regex security checks in code review process
References
Just to give a content for those who don't want to read the whole text. There seems to be a potential issue in the mocha regex tests. So there is no effect on anything production/public facing.
I would love to work on this issue @StorytellerCZ @italojs Please assign me with this (if not fixed yet)
@Abhyshekbhalaji then work on it and submit a PR. Only core teams gets assigned to issues, we have assigned people to issues in the past and then never heard from them again, so we no longer assign unknown people. Also there already is a PR for part of this issue, so be sure to take that into account.
But https://github.com/meteor/meteor/pull/13936 doesn't fix it?
https://github.com/meteor/meteor/pull/13936 fixes the issue reported here, but the suggestion is to also include additional utilities to check for this in future submitted code. Given that this issue is only in few tests it is not something urgent or impactful. After merging the PR I'm fine with closing this issue.
I'm interested in working on this issue. Could you provide more context about what you're looking for? Any additional details about requirements or constraints would be helpful.