UNPKG

tl-shared-security

Version:

Enterprise-grade security module for frontend and backend applications with comprehensive protection against XSS, CSRF, SQL injection, and other security vulnerabilities

116 lines 3.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.contentSecurity = exports.ContentSecurity = void 0; const xssSanitizer_1 = require("./xssSanitizer"); class ContentSecurity { constructor(options) { this.options = { allowedDomains: [], allowDataUrls: false, allowBlobUrls: false, allowRelativeUrls: true, ...options, }; } /** * Validates if a URL is safe according to the security policy * @param url - URL to validate * @returns True if URL is safe, false otherwise */ isSafeUrl(url) { if (!url) return false; // Sanitize URL first const sanitized = (0, xssSanitizer_1.sanitizeUrl)(url); if (!sanitized) return false; try { // Check for relative URLs if (url.startsWith('/') && !url.startsWith('//')) { return this.options.allowRelativeUrls ?? true; } // Check for data URLs if (url.startsWith('data:')) { return this.options.allowDataUrls ?? false; } // Check for blob URLs if (url.startsWith('blob:')) { return this.options.allowBlobUrls ?? false; } // Parse URL to check domain const urlObj = new URL(url); // Check against allowed domains if (this.options.allowedDomains && this.options.allowedDomains.length > 0) { return this.options.allowedDomains.some(domain => urlObj.hostname === domain || urlObj.hostname.endsWith(`.${domain}`)); } return true; } catch (error) { return false; } } /** * Creates a safe URL - returns the URL if safe, or a fallback if not * @param url - URL to check * @param fallback - Fallback URL if unsafe * @returns Safe URL or fallback */ createSafeUrl(url, fallback = '#') { return this.isSafeUrl(url) ? url : fallback; } /** * Validates if an image source is safe * @param src - Image source URL * @returns True if image source is safe, false otherwise */ isSafeImageSrc(src) { // Allow data URLs for images if configured if (src.startsWith('data:image/') && this.options.allowDataUrls) { return true; } return this.isSafeUrl(src); } /** * Creates a safe image source - returns the source if safe, or a fallback if not * @param src - Image source to check * @param fallback - Fallback image source if unsafe * @returns Safe image source or fallback */ createSafeImageSrc(src, fallback = '') { return this.isSafeImageSrc(src) ? src : fallback; } /** * Validates if HTML content is safe * @param html - HTML content to validate * @returns True if HTML content is safe, false otherwise */ isSafeHtml(html) { if (!html) return true; // Check for script tags if (/<script\b[^>]*>([\s\S]*?)<\/script>/i.test(html)) { return false; } // Check for event handlers if (/\son\w+\s*=\s*(['"])/i.test(html)) { return false; } // Check for iframe tags if (/<iframe\b[^>]*>([\s\S]*?)<\/iframe>/i.test(html)) { return false; } // Check for object tags if (/<object\b[^>]*>([\s\S]*?)<\/object>/i.test(html)) { return false; } // Check for embed tags if (/<embed\b[^>]*>/i.test(html)) { return false; } return true; } } exports.ContentSecurity = ContentSecurity; // Export default instance exports.contentSecurity = new ContentSecurity(); //# sourceMappingURL=content-security.js.map