various improvements and performance enhancements

This commit is contained in:
Stefan Hardegger
2025-08-12 14:55:51 +02:00
parent 75c207970d
commit c46108c317
11 changed files with 380 additions and 32 deletions

View File

@@ -5,7 +5,8 @@ interface SanitizationConfig {
allowedTags: string[];
allowedAttributes: Record<string, string[]>;
allowedCssProperties: string[];
removedAttributes: Record<string, string[]>;
removedAttributes?: Record<string, string[]>;
allowedProtocols?: Record<string, Record<string, string[]>>;
description: string;
}
@@ -95,8 +96,10 @@ async function fetchSanitizationConfig(): Promise<SanitizationConfig> {
'font-style', 'text-align', 'text-decoration', 'margin',
'padding', 'text-indent', 'line-height'
],
removedAttributes: {
'a': ['href', 'target']
allowedProtocols: {
'a': {
'href': ['http', 'https', '#', '/']
}
},
description: 'Fallback sanitization configuration'
};
@@ -114,10 +117,10 @@ function createDOMPurifyConfig(config: SanitizationConfig) {
const allowedTags = config.allowedTags;
const allowedAttributes: Record<string, string[]> = { ...config.allowedAttributes };
// Remove attributes that should be stripped (like href from links)
// Remove attributes that should be stripped (deprecated, keeping for backward compatibility)
if (config.removedAttributes) {
Object.keys(config.removedAttributes).forEach(tag => {
const attributesToRemove = config.removedAttributes[tag];
const attributesToRemove = config.removedAttributes![tag];
if (allowedAttributes[tag]) {
allowedAttributes[tag] = allowedAttributes[tag].filter(
attr => !attributesToRemove.includes(attr)
@@ -132,9 +135,20 @@ function createDOMPurifyConfig(config: SanitizationConfig) {
const flattenedAttributes = Object.values(allowedAttributes).flat();
const uniqueAttributes = Array.from(new Set(flattenedAttributes));
// Configure allowed protocols for URL validation
const allowedSchemes: string[] = [];
if (config.allowedProtocols) {
Object.values(config.allowedProtocols).forEach(attributeProtocols => {
Object.values(attributeProtocols).forEach(protocols => {
allowedSchemes.push(...protocols);
});
});
}
const domPurifyConfig: DOMPurify.Config = {
ALLOWED_TAGS: allowedTags,
ALLOWED_ATTR: uniqueAttributes,
ALLOWED_URI_REGEXP: /^(?:(?:https?|#|\/):?\/?)[\w.\-#/?=&%]+$/i,
ALLOW_UNKNOWN_PROTOCOLS: false,
SANITIZE_DOM: true,
KEEP_CONTENT: true,