"use strict"; /** * Input Sanitization Utilities * Protects against XSS, prompt injection, and other injection attacks */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.safeSanitize = exports.sanitizeWebhookPayload = exports.sanitizePath = exports.sanitizePrompt = exports.escapeShellArg = exports.escapeRegex = exports.sanitizeHTML = void 0; const dompurify_1 = __importDefault(require("dompurify")); const jsdom_1 = require("jsdom"); const window = new jsdom_1.JSDOM('').window; const DOMPurify = (0, dompurify_1.default)(window); // DOMPurify config for strict sanitization const PURIFY_CONFIG = { ALLOWED_TAGS: [], // No HTML tags allowed ALLOWED_ATTR: [], // No attributes allowed KEEP_CONTENT: true // Keep text content }; /** * Sanitize user input to remove HTML/JS * Use for: Issue comments, PR descriptions, user-generated content */ const sanitizeHTML = (input) => { if (!input) return ''; return DOMPurify.sanitize(input, PURIFY_CONFIG); }; exports.sanitizeHTML = sanitizeHTML; /** * Escape special regex characters * Use for: Preventing regex injection */ const escapeRegex = (input) => { return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }; exports.escapeRegex = escapeRegex; /** * Escape shell command arguments * Use for: Preventing command injection in exec calls */ const escapeShellArg = (arg) => { // Remove null bytes and escape quotes return arg.replace(/\x00/g, '').replace(/["'`]/g, ''); }; exports.escapeShellArg = escapeShellArg; /** * Sanitize AI prompt input * Prevents prompt injection attacks */ const sanitizePrompt = (input) => { if (!input) return ''; // Remove common prompt injection patterns const dangerousPatterns = [ /ignore previous instructions/gi, /disregard (the|all|any) (above|previous|prior)/gi, /system prompt/gi, /you are now/gi, /new instructions/gi, /===END.*===/gi, // Pattern markers /<\|endoftext\|>/gi, // GPT end markers /\[SYSTEM\]/gi, /\[INSTRUCTION\]/gi, /\[PROMPT\]/gi ]; let sanitized = input; for (const pattern of dangerousPatterns) { sanitized = sanitized.replace(pattern, '[REDACTED]'); } // Also apply HTML sanitization return (0, exports.sanitizeHTML)(sanitized); }; exports.sanitizePrompt = sanitizePrompt; /** * Sanitize filename/path input * Prevents path traversal attacks */ const sanitizePath = (input) => { if (!input) return ''; // Remove path traversal patterns return input .replace(/\.\./g, '') // Remove parent directory references .replace(/^[\/\\]/, '') // Remove leading slashes .replace(/\x00/g, ''); // Remove null bytes }; exports.sanitizePath = sanitizePath; /** * Validate and sanitize webhook payload */ const sanitizeWebhookPayload = (payload) => { if (typeof payload !== 'object' || payload === null) { return payload; } const sanitized = {}; for (const [key, value] of Object.entries(payload)) { if (typeof value === 'string') { // Sanitize string values sanitized[key] = (0, exports.sanitizeHTML)(value); } else if (typeof value === 'object' && value !== null) { // Recursively sanitize nested objects sanitized[key] = (0, exports.sanitizeWebhookPayload)(value); } else { // Keep primitives as-is sanitized[key] = value; } } return sanitized; }; exports.sanitizeWebhookPayload = sanitizeWebhookPayload; /** * Rate limiting helper for sanitization * Prevents ReDoS attacks on regex sanitization */ const safeSanitize = (input, sanitizer, maxLength = 100000) => { if (!input) return ''; // Truncate very long inputs to prevent ReDoS const truncated = input.length > maxLength ? input.substring(0, maxLength) + '... [truncated]' : input; return sanitizer(truncated); }; exports.safeSanitize = safeSanitize; //# sourceMappingURL=sanitizer.js.map