security: path validation, ReDoS prevention, picomatch, PID-based file lock
- Add validateProjectPath() to reject sensitive system directories - Add isPathWithinRoot/isPathWithinRootReal for symlink-aware path checks - Replace hand-rolled glob-to-regex with picomatch to prevent ReDoS - Add isSafeRegex() to reject custom patterns with nested quantifiers - Replace FileLock with PID-tracking version that detects stale locks - Add symlink detection in removeDirectory/listDirectoryContents - Add subdirectory name validation in ensureSubdirectory - Add atomicWriteFileSync and corrupted file backup in config-writer - Add MCP input validation (validateString) for all tool handlers - Fix CLAUDE.md section replacement to handle ### subsections correctly
This commit is contained in:
+2
-20
@@ -68,26 +68,8 @@ export function hashContent(content: string): string {
|
||||
* Check if a path matches any glob pattern (simplified)
|
||||
*/
|
||||
function matchesGlob(filePath: string, pattern: string): boolean {
|
||||
// Convert glob to regex using placeholders to avoid conflicts
|
||||
let regexStr = pattern;
|
||||
|
||||
// Replace glob patterns with placeholders first
|
||||
regexStr = regexStr.replace(/\*\*\//g, '\x00GLOBSTAR_SLASH\x00');
|
||||
regexStr = regexStr.replace(/\*\*/g, '\x00GLOBSTAR\x00');
|
||||
regexStr = regexStr.replace(/\*/g, '\x00STAR\x00');
|
||||
regexStr = regexStr.replace(/\?/g, '\x00QUESTION\x00');
|
||||
|
||||
// Escape regex special characters
|
||||
regexStr = regexStr.replace(/[.+^${}()|[\]\\]/g, '\\$&');
|
||||
|
||||
// Replace placeholders with regex equivalents
|
||||
regexStr = regexStr.replace(/\x00GLOBSTAR_SLASH\x00/g, '(?:.*/)?'); // **/ = zero or more dirs
|
||||
regexStr = regexStr.replace(/\x00GLOBSTAR\x00/g, '.*'); // ** = anything
|
||||
regexStr = regexStr.replace(/\x00STAR\x00/g, '[^/]*'); // * = anything except /
|
||||
regexStr = regexStr.replace(/\x00QUESTION\x00/g, '.'); // ? = single char
|
||||
|
||||
const regex = new RegExp(`^${regexStr}$`);
|
||||
return regex.test(filePath);
|
||||
const picomatch = require('picomatch');
|
||||
return picomatch.isMatch(filePath, pattern, { dot: true });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user