UNPKG

pi-lens

Version:

Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo

75 lines (60 loc) • 2.02 kB
# Unsafe Regex Construction # Detects dynamic regex construction that can lead to ReDoS id: unsafe-regex name: Dynamic Regex Construction severity: error category: security defect_class: injection inline_tier: blocking language: typescript message: "Dynamic regex from user input — can cause ReDoS (Regular Expression Denial of Service)" description: | Building regular expressions from user input or dynamic strings can lead to ReDoS attacks. An attacker can craft input that causes catastrophic backtracking. ❌ NEVER: const regex = new RegExp(userInput, 'i'); // ReDoS risk! const pattern = new RegExp(`\\b${term}\\b`); // Also risky! ✅ SAFE ALTERNATIVES: 1. Escape special regex characters before interpolation 2. Use string methods instead of regex when possible 3. Validate input against a whitelist Example escaping: function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } const regex = new RegExp(escapeRegExp(userInput), 'i'); query: | (new_expression constructor: (identifier) @CTOR (#eq? @CTOR "RegExp") arguments: (arguments (template_string (template_substitution) @INTERPOLATION) @PATTERN) (#not-match? @INTERPOLATION "escape|Escape|replace")) metavars: - CTOR - INTERPOLATION - PATTERN has_fix: false tags: - security - regex - redos - injection examples: bad: | // ReDoS vulnerability! const searchRegex = new RegExp(`\\b${userSearch}\\b`, 'gi'); // Also vulnerable const validator = new RegExp(req.body.pattern); good: | // Safe: Escape special characters function escapeRegExp(string: string): string { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } const safeRegex = new RegExp(escapeRegExp(userSearch), 'i'); // Safe: Use string methods const found = text.toLowerCase().includes(userSearch.toLowerCase()); // Safe: Static regex const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;