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
JavaScript
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
;