UNPKG

dev-lamp

Version:

Your friendly lighthouse performance companion - 100% local

83 lines 3.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PathSanitizer = void 0; const path_1 = require("path"); class PathSanitizer { static DANGEROUS_PATTERNS = [ /\.\./g, // Parent directory traversal /~\//g, // Home directory access /^\//, // Absolute paths (on Unix) /^[A-Z]:\\/i, // Absolute paths (on Windows) /\0/g, // Null bytes /<|>|:|"|\\|\||\?|\*/g // Invalid filename characters ]; static MAX_PATH_LENGTH = 255; static SAFE_EXTENSIONS = ['.md', '.txt', '.json', '.html']; static sanitizeOutputPath(path) { if (!path || path.length === 0) { return { safe: false, error: 'Output path is required' }; } // Check length if (path.length > this.MAX_PATH_LENGTH) { return { safe: false, error: `Path exceeds maximum length of ${this.MAX_PATH_LENGTH} characters` }; } // Normalize the path let normalizedPath = (0, path_1.normalize)(path); // Reject absolute paths if ((0, path_1.isAbsolute)(normalizedPath)) { // Convert to relative path in current directory normalizedPath = (0, path_1.basename)(normalizedPath); } // Check for dangerous patterns for (const pattern of this.DANGEROUS_PATTERNS) { if (pattern.test(normalizedPath)) { return { safe: false, error: 'Path contains invalid or dangerous characters' }; } } // Check for path traversal attempts if (normalizedPath.includes('..') || normalizedPath.includes('./')) { return { safe: false, error: 'Path traversal attempts are not allowed' }; } // Ensure safe extension const hasValidExtension = this.SAFE_EXTENSIONS.some(ext => normalizedPath.toLowerCase().endsWith(ext)); if (!hasValidExtension) { // Add default extension if none provided if (!normalizedPath.includes('.')) { normalizedPath += '.md'; } else { return { safe: false, error: 'Invalid file extension. Allowed: ' + this.SAFE_EXTENSIONS.join(', ') }; } } // Resolve to safe path const safePath = (0, path_1.resolve)(process.cwd(), normalizedPath); // Final check: ensure the resolved path is within current directory if (!safePath.startsWith(process.cwd())) { return { safe: false, error: 'Output path must be within current directory' }; } return { safe: true, sanitized: normalizedPath }; } static sanitizeFilename(filename) { // Remove any directory separators let safe = (0, path_1.basename)(filename); // Remove dangerous characters safe = safe.replace(/[<>:"|?*\\/]/g, '-'); // Remove control characters safe = safe.replace(/[\x00-\x1f\x7f]/g, ''); // Limit length if (safe.length > 200) { const ext = safe.lastIndexOf('.'); if (ext > 0) { const name = safe.substring(0, ext); const extension = safe.substring(ext); safe = name.substring(0, 200 - extension.length) + extension; } else { safe = safe.substring(0, 200); } } return safe || 'report'; } } exports.PathSanitizer = PathSanitizer; //# sourceMappingURL=path-sanitizer.js.map