dev-lamp
Version:
Your friendly lighthouse performance companion - 100% local
83 lines • 3.49 kB
JavaScript
;
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