Input Sanitization

132 LOC · The security backbone shared by both the Service Worker and the Loader. Uses the battle-tested xss library (js-xss) as the primary filter, with additional defense-in-depth layers for URI schemes, event handlers, and JSON injection.

Architecture

Works in both contexts without DOM dependency:

Service Worker

sanitizeUrlParams() on every fetch intercepted URL.safeJsonForScript() before HTML injection.

Loader (Main Thread)

sanitizeValue() on fallback parameter capture. Also used on referrer in message handler.

sanitizeValue() — 5-Layer Pipeline

Each value passes through 5 sequential security layers:

LayerProtectionImplementation
1. XSS LibraryHTML tag strippingxssFilter(value, options) — strips ALL HTML tags, removes script/style/iframe/object/embed/form body content
2. Control CharsNull bytes & invisible charactersRegex removes \0 and control chars \x01-\x08, \x0B, \x0C, \x0E-\x1F, \x7F
3. URI SchemesJavaScript/Data/VBScript executionReplaces javascript:, data:, vbscript: with blocked:
4. Event HandlersDOM event injectionReplaces onXxx= patterns with blocked=
5. TruncationDoS / buffer overflowMax 500 characters per value (MAX_PARAM_LENGTH)

XSS Library Configuration

const XSS_OPTIONS = {
  whiteList: {},                // No tags allowed at all
  stripIgnoreTag: true,         // Strip tags not in whitelist
  stripIgnoreTagBody: [         // Remove entire content of dangerous tags:
    'script', 'style', 'noscript',
    'iframe', 'object', 'embed', 'form'
  ],
  stripBlankChar: true,         // Remove zero-width chars
  onIgnoreTagAttr: () => '',    // Remove all attributes
  escapeHtml: (html) => html    // Don't double-encode (we want text, not entities)
};

sanitizeUrlParams() — Parameter Protection

Additional security measures applied at the parameter level:

ProtectionLimitPurpose
Param count limit50 params maxAnti-DoS: prevents processing thousands of params
Key sanitization[a-zA-Z0-9_\-\.~] only, 100 char maxRestricts keys to safe character set
Prototype pollutionBlock __proto__, constructor, prototypePrevents object prototype manipulation
Value sanitizationFull sanitizeValue() pipeline5-layer XSS protection on every value

safeJsonForScript() — Injection Prevention

Applied after JSON.stringify() and before inline<script> injection. Prevents context-escape attacks:

CharacterEscaped ToAttack Prevented
<\u003c</script> breakout
>\u003eTag injection
$\u0024Template literal injection
U+2028\u2028JS line separator (syntax break)
U+2029\u2029JS paragraph separator
&\u0026HTML entity injection
'\u0027Single-quote breakout
=\u003dAttribute injection

Constants

ConstantValuePurpose
MAX_PARAM_LENGTH500Max characters per parameter value
MAX_PARAMS_COUNT50Max number of URL parameters processed

Exports

// Named exports used by service-worker.js and loader.js:
export { sanitizeValue }       // Single value sanitization
export { sanitizeUrlParams }   // Full URL params sanitization
export { safeJsonForScript }   // JSON injection escaping
export { MAX_PARAM_LENGTH }    // For external validation
export { MAX_PARAMS_COUNT }    // For external validation