Custom Configuration Define your own security rules:
`typescript import { HtmlSanitizer } from '@bernierllc/html-sanitizer';const sanitizer = new HtmlSanitizer({ allowedTags: ['p', 'a', 'strong', 'em'], allowedAttributes: { 'a': ['href', 'title'] }, allowedProtocols: ['https'], // Only HTTPS links allowStyles: false, allowDataUris: false });
const result = sanitizer.sanitize(userHtml);
`
API Reference
$3 Main class for HTML sanitization.
#### Constructor
` - Allowed attributes per tag - allowedProtocols?: string[] - Allowed URL protocols - allowStyles?: boolean - Allow inline styles (default: false) - allowDataUris?: boolean - Allow data: URIs (default: false) - mode?: 'strict' | 'moderate' | 'relaxed' - Use predefined profile#### Methods
sanitize(html: string): SanitizationResultSanitize HTML and get detailed report:
`typescript const result = sanitizer.sanitize(html);// SanitizationResult: { html: string; // Sanitized HTML modified: boolean; // Whether content was changed removedTags: string[]; // Tags that were removed removedAttributes: Array<{ // Attributes that were removed tag: string; attribute: string; }>; xssPatterns: string[]; // XSS patterns detected warnings: string[]; // Security warnings }
`
sanitizeWithProfile(html: string, profile: SanitizationProfile): SanitizationResultSanitize using a specific profile:
`typescript const result = sanitizer.sanitizeWithProfile(html, SanitizationProfile.STRICT);`
validate(html: string): ValidationResultCheck if HTML is safe without modifying:
`typescript const result = sanitizer.validate(html);// ValidationResult: { safe: boolean; // Whether HTML is safe issues: string[]; // List of security issues }
`
$3
sanitizeHtml(html: string, config?: SanitizerConfig): stringQuick sanitization, returns clean HTML string:
`typescript import { sanitizeHtml } from '@bernierllc/html-sanitizer';const clean = sanitizeHtml(userInput);
`
sanitizeWithProfile(html: string, profile: SanitizationProfile): stringSanitize with a profile, returns clean HTML string:
`typescript import { sanitizeWithProfile, SanitizationProfile } from '@bernierllc/html-sanitizer';const clean = sanitizeWithProfile(userInput, SanitizationProfile.STRICT);
`
validateHtml(html: string): { safe: boolean; issues: string[] }Validate HTML safety:
`typescript import { validateHtml } from '@bernierllc/html-sanitizer';const result = validateHtml(userInput); if (!result.safe) { console.error('Unsafe HTML:', result.issues); }
`
XSS Attack Prevention This package protects against all common XSS attack vectors:
$3
`typescript const html = 'Hello
'; const result = sanitizer.sanitize(html);// result.html: '
Hello
' // result.removedTags: ['script'] // result.xssPatterns: ['script tag'] // result.warnings: ['CRITICAL: Dangerous executable content removed']`
$3
`typescript const html = ' '; const result = sanitizer.sanitize(html);// onerror attribute removed // result.xssPatterns: ['event handler']
`
$3
`typescript const html = 'Click '; const result = sanitizer.sanitize(html);// javascript: protocol removed // result.xssPatterns: ['javascript: protocol']
`
$3
`typescript const html = ' '; const result = sanitizer.sanitize(html);// Detected and blocked // result.xssPatterns: ['data: URI']
`
$3
`typescript const html = ' '; const result = sanitizer.sanitize(html);// and tags always removed // result.removedTags: ['object']
`
Security Best Practices
$3
`typescript // ✅ CORRECT app.post('/comment', (req, res) => { const sanitized = sanitizeHtml(req.body.comment); await saveComment(sanitized); });// ❌ WRONG - Never trust user input app.post('/comment', (req, res) => { await saveComment(req.body.comment); // Dangerous! });
`
$3
`typescript // Comments: Use STRICT const comment = sanitizeWithProfile(userComment, SanitizationProfile.STRICT);// Blog posts: Use MODERATE (default) const blogPost = sanitizeHtml(userBlogPost);
// Admin content: Use RELAXED (only for trusted users) if (user.isAdmin) { const adminContent = sanitizeWithProfile(userContent, SanitizationProfile.RELAXED); }
`
$3
`typescript const result = sanitizer.sanitize(userHtml);if (result.xssPatterns.length > 0) { // Log security event logger.warn('XSS attempt detected', { userId: user.id, patterns: result.xssPatterns, removedTags: result.removedTags }); }
`
$3
`typescript const validation = validateHtml(userInput);if (!validation.safe) { return res.status(400).json({ error: 'Content contains unsafe HTML', issues: validation.issues }); }
`
Performance - Typical blog post (5KB) : <10ms - Large content (500KB) : <100ms - Memory usage : <50MB for large content
Built on DOMPurify, which is highly optimized and used by millions of websites.
Integration Status
$3 Status : Optional (recommended for security monitoring)Justification : While this package can function without logging, it's highly recommended to integrate
@bernierllc/logger for security event monitoring. The sanitizer can detect and remove XSS patterns, and logging these events helps with security auditing and threat detection. However, the package is designed to work without logging for environments where logging isn't available.Pattern : Optional integration - package works without logger, but logger enhances security monitoring capabilities.
Example Integration :
`typescript import { Logger } from '@bernierllc/logger'; import { HtmlSanitizer } from '@bernierllc/html-sanitizer';const logger = new Logger({ service: 'html-sanitizer' }); const sanitizer = new HtmlSanitizer();
const result = sanitizer.sanitize(userHtml); if (result.xssPatterns.length > 0) { logger.warn('XSS attempt detected', { patterns: result.xssPatterns, removedTags: result.removedTags }); }
`
$3 Status : Not applicableJustification : This is a core utility package that performs HTML sanitization. It does not participate in service discovery, event publishing, or service mesh operations. While security events could theoretically be published to NeverHub, this package focuses solely on sanitization logic and delegates event handling to calling code.
Pattern : Core utility - no service mesh integration needed. Security events should be handled by the application layer that uses this sanitizer.
$3 Status : ReadyFormat : TypeDoc-compatible JSDoc comments are included throughout the source code. All public APIs are documented with examples and type information.
Dependencies - dompurify (^3.1.7) - HTML sanitization engine - jsdom (^25.0.1) - DOM implementation for Node.js
Development
`bashInstall dependencies npm install
Run tests npm test
Run tests with coverage npm run test:coverage
Build package npm run build
Lint code npm run lint`
Testing This package has comprehensive test coverage (90%+) including:
- XSS attack prevention (script tags, event handlers, protocols) - All security profiles (strict, moderate, relaxed) - Custom configuration options - Edge cases (malformed HTML, Unicode, large input) - Sanitization result metadata
Related Packages
$3 - dompurify (npm) - HTML sanitization engine - jsdom (npm) - DOM implementation
$3 - @bernierllc/content-transformer - Content format conversions - @bernierllc/content-editor-service - Editor backend - @bernierllc/markdown-renderer` - HTML output sanitization
$3 - Content Management Suite - Blog content and commit message workflows
License Copyright (c) 2025 Bernier LLC
This file is licensed to the client under a limited-use license. The client may use and modify this code only within the scope of the project it was delivered for . Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
Security For security concerns or to report vulnerabilities, please contact: security@bernierllc.com
This is a security-critical package. All XSS vulnerabilities are treated as high priority.