diff --git a/README.md b/README.md index 92b34b8..4f5923a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DOMFortify -[![npm](https://img.shields.io/npm/v/domfortify.svg)](https://www.npmjs.com/package/domfortify) [![License](https://img.shields.io/badge/license-MPL--2.0%20OR%20Apache--2.0-blue.svg)](https://github.com/cure53/DOMFortify/blob/main/LICENSE) ![npm package minimized gzipped size](https://img.shields.io/bundlejs/size/domfortify?color=%233C1&label=gzip) [![Build & Test](https://github.com/cure53/DOMFortify/actions/workflows/build-and-test.yml/badge.svg?branch=main)](https://github.com/cure53/DOMFortify/actions/workflows/build-and-test.yml) [![CodeQL](https://github.com/cure53/DOMFortify/actions/workflows/codeql-analysis.yml/badge.svg?branch=main)](https://github.com/cure53/DOMFortify/actions/workflows/codeql-analysis.yml) +[![npm](https://img.shields.io/npm/v/domfortify.svg)](https://www.npmjs.com/package/domfortify) [![License](https://img.shields.io/badge/license-MPL--2.0%20OR%20Apache--2.0-blue.svg)](https://github.com/cure53/DOMFortify/blob/main/LICENSE) ![npm package minimized gzipped size](https://img.shields.io/bundlejs/size/domfortify?color=%233C1&label=gzip) [![Build & Test](https://github.com/cure53/DOMFortify/actions/workflows/build-and-test.yml/badge.svg?branch=main)](https://github.com/cure53/DOMFortify/actions/workflows/build-and-test.yml) [![CodeQL](https://github.com/cure53/DOMFortify/actions/workflows/codeql-analysis.yml/badge.svg?branch=main)](https://github.com/cure53/DOMFortify/actions/workflows/codeql-analysis.yml) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/13287/badge)](https://www.bestpractices.dev/projects/13287) [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/cure53/DOMFortify/badge)](https://scorecard.dev/viewer/?uri=github.com/cure53/DOMFortify) [![Socket Badge](https://badge.socket.dev/npm/package/domfortify/latest)](https://badge.socket.dev/npm/package/domfortify/latest) diff --git a/dist/fortify.cjs.js b/dist/fortify.cjs.js index ae5bbcc..64fd9cd 100644 --- a/dist/fortify.cjs.js +++ b/dist/fortify.cjs.js @@ -137,17 +137,37 @@ function selectOverride(options, url) { return null; for (let i = 0; i < rules.length; i++) { const r = rules[i]; - if (r && urlMatches(r.match, url)) + // Read `match` own-key only, so a polluted Object.prototype.match can't make a rule that lacks + // its own match apply to every URL. + if (r && typeof r === 'object' && urlMatches(cfg(r, 'match'), url)) { return r; + } } return null; } +// Does `raw` carry a `.sanitize` method of its own (or on its own class prototype), as opposed to one +// merely inherited from Object.prototype? We walk the chain but STOP before Object.prototype, so a +// polluted Object.prototype.sanitize is never mistaken for a real sanitizer. Class-based sanitizers, +// whose method lives on their own prototype below Object.prototype, still qualify. Tolerant of a +// hostile getter on the lookup path, which is treated as "not a sanitizer". +function looksLikeSanitizer(raw) { + try { + for (let o = raw; o && o !== Object.prototype; o = Object.getPrototypeOf(o)) { + if (own(o, 'sanitize')) + return typeof o.sanitize === 'function'; + } + } + catch { + /* a throwing getter on the chain means we cannot trust it as a sanitizer */ + } + return false; +} // Normalize whatever the caller handed us into a sanitizer with a `.sanitize` method, or null. // DOMPurify's export is itself a callable factory that ALSO carries `.sanitize`, so we must check for // `.sanitize` FIRST - otherwise we'd wrap the factory and call the wrong thing. A bare function (e.g. a // Sanitizer-API adapter) has no `.sanitize` and falls through to the function case. function resolveSanitizer(raw) { - if (raw && typeof raw.sanitize === 'function') + if (raw && looksLikeSanitizer(raw)) return raw; if (typeof raw === 'function') return { sanitize: raw }; @@ -262,84 +282,92 @@ function init(options = {}) { report(code, cachedStatus); return cachedStatus; }; - const url = loc && typeof loc.href !== 'undefined' ? String(loc.href) : ''; - // EXCLUDE: on a match, stay completely out of the way - no policy, no meta. We do NOT install a - // passthrough (that would be a silent XSS hole); under globally delivered enforcement, excluded - // pages are the developer's responsibility. Reported via status.excluded. - if (urlMatches(cfg(options, 'EXCLUDE'), url)) { - status.excluded = true; - return done('URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.', 'excluded-by-url'); - } - if (!TT || typeof TT.createPolicy !== 'function') { - return done('Trusted Types not supported; library is inert. Sinks are NOT routed.', 'tt-unsupported'); - } - // Resolve config once. `eff(key)` reads the matching URL_CONFIG rule's own key when present, else the - // base config - both own-key only. Nothing is re-read later, so runtime clobbering can't retarget - // the policy after this point either. - const override = selectOverride(options, url); - const eff = (key) => (override && own(override, key) ? override[key] : cfg(options, key)); - // INJECT_META (opt-in, best-effort - see injectMeta and the README). - if (cfg(options, 'INJECT_META') === true) { - const directive = metaDirective(cfg(options, 'META_DIRECTIVE'), typeof eff('SANITIZER') === 'function'); - status.metaInjected = injectMeta(directive); - report('meta-injection-attempted', { directive, written: status.metaInjected }); - } - status.enforcementActive = enforcementActive(); - // Sanitizer: explicit SANITIZER (possibly per-URL), else window.DOMPurify. Config is forwarded - // verbatim as the second argument, copied to drop pollution-prone keys. - let rawSan = eff('SANITIZER'); - if (rawSan === undefined) - rawSan = root.DOMPurify; - const sanitizer = resolveSanitizer(rawSan); - const rawCfg = eff('SANITIZER_CONFIG'); - const sanitizeConfig = rawCfg && typeof rawCfg === 'object' ? shallowCopy(rawCfg) : undefined; - // Sink openers count only if they're own functions, so prototype pollution can never open a sink. - const asCand = eff('ALLOW_SCRIPT'); - const asuCand = eff('ALLOW_SCRIPT_URL'); - const allowScript = typeof asCand === 'function' ? asCand : null; - const allowScriptURL = typeof asuCand === 'function' ? asuCand : null; - let sanitizerReady = false; - if (sanitizer) { - const result = smokeTest(sanitizer, sanitizeConfig); - sanitizerReady = result.ready; - if (!result.ready) - report('sanitizer-smoketest-failed', { error: result.error }); - } - status.sanitizerReady = sanitizerReady; - // createHTML closes over sanitizeConfig; the script hooks refuse unless an own-function hook allows. - const policyDef = { - createHTML: makeSanitizeHTML(sanitizer, sanitizeConfig, sanitizerReady, report), - createScript: makeScriptHook('createScript', allowScript, report), - createScriptURL: makeScriptHook('createScriptURL', allowScriptURL, report), - }; - // Did someone grab the default slot first? We can't evict them and won't vouch for them. - if (TT.defaultPolicy) { - return done('A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. ' + - 'Load DOMFortify first, inline in .', 'preexisting-default-policy'); - } - let ours; try { - ours = TT.createPolicy('default', policyDef); + const url = loc && typeof loc.href !== 'undefined' ? String(loc.href) : ''; + // EXCLUDE: on a match, stay completely out of the way - no policy, no meta. We do NOT install a + // passthrough (that would be a silent XSS hole); under globally delivered enforcement, excluded + // pages are the developer's responsibility. Reported via status.excluded. + if (urlMatches(cfg(options, 'EXCLUDE'), url)) { + status.excluded = true; + return done('URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.', 'excluded-by-url'); + } + if (!TT || typeof TT.createPolicy !== 'function') { + return done('Trusted Types not supported; library is inert. Sinks are NOT routed.', 'tt-unsupported'); + } + // Resolve config once. `eff(key)` reads the matching URL_CONFIG rule's own key when present, else the + // base config - both own-key only. Nothing is re-read later, so runtime clobbering can't retarget + // the policy after this point either. + const override = selectOverride(options, url); + const eff = (key) => (override && own(override, key) ? override[key] : cfg(options, key)); + // INJECT_META (opt-in, best-effort - see injectMeta and the README). + if (cfg(options, 'INJECT_META') === true) { + const directive = metaDirective(cfg(options, 'META_DIRECTIVE'), typeof eff('SANITIZER') === 'function'); + status.metaInjected = injectMeta(directive); + report('meta-injection-attempted', { directive, written: status.metaInjected }); + } + status.enforcementActive = enforcementActive(); + // Sanitizer: explicit SANITIZER (possibly per-URL), else window.DOMPurify. Config is forwarded + // verbatim as the second argument, copied to drop pollution-prone keys. + let rawSan = eff('SANITIZER'); + if (rawSan === undefined) + rawSan = root.DOMPurify; + const sanitizer = resolveSanitizer(rawSan); + const rawCfg = eff('SANITIZER_CONFIG'); + const sanitizeConfig = rawCfg && typeof rawCfg === 'object' ? shallowCopy(rawCfg) : undefined; + // Sink openers count only if they're own functions, so prototype pollution can never open a sink. + const asCand = eff('ALLOW_SCRIPT'); + const asuCand = eff('ALLOW_SCRIPT_URL'); + const allowScript = typeof asCand === 'function' ? asCand : null; + const allowScriptURL = typeof asuCand === 'function' ? asuCand : null; + let sanitizerReady = false; + if (sanitizer) { + const result = smokeTest(sanitizer, sanitizeConfig); + sanitizerReady = result.ready; + if (!result.ready) + report('sanitizer-smoketest-failed', { error: result.error }); + } + status.sanitizerReady = sanitizerReady; + // createHTML closes over sanitizeConfig; the script hooks refuse unless an own-function hook allows. + const policyDef = { + createHTML: makeSanitizeHTML(sanitizer, sanitizeConfig, sanitizerReady, report), + createScript: makeScriptHook('createScript', allowScript, report), + createScriptURL: makeScriptHook('createScriptURL', allowScriptURL, report), + }; + // Did someone grab the default slot first? We can't evict them and won't vouch for them. + if (TT.defaultPolicy) { + return done('A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. ' + + 'Load DOMFortify first, inline in .', 'preexisting-default-policy'); + } + let ours; + try { + ours = TT.createPolicy('default', policyDef); + } + catch (e) { + // Throws when a default policy exists and 'allow-duplicates' is off - someone won the race. + return done(`createPolicy("default") threw (${emsg(e)}); another default policy won the race.`, 'default-policy-lost'); + } + // With 'allow-duplicates' the create can succeed yet not be the active default. + if (TT.defaultPolicy && TT.defaultPolicy !== ours) { + return done('Our policy was created but is not the active default (allow-duplicates race lost). ' + + 'Remove "allow-duplicates" from the trusted-types directive.', 'default-policy-not-active'); + } + status.defaultPolicyOwned = true; + if (!status.enforcementActive) { + return done('Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. ' + + 'Deliver require-trusted-types-for (header preferred).', 'enforcement-inactive'); + } + if (!sanitizerReady) { + return done('Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW ' + + '(failing closed). Bundle DOMPurify and load it before DOMFortify.', 'failing-closed'); + } + return done(`Active: HTML sinks sanitized, script sinks ${allowScript || allowScriptURL ? 'partly allowed by hooks' : 'refused'}.`); } catch (e) { - // Throws when a default policy exists and 'allow-duplicates' is off - someone won the race. - return done(`createPolicy("default") threw (${emsg(e)}); another default policy won the race.`, 'default-policy-lost'); - } - // With 'allow-duplicates' the create can succeed yet not be the active default. - if (TT.defaultPolicy && TT.defaultPolicy !== ours) { - return done('Our policy was created but is not the active default (allow-duplicates race lost). ' + - 'Remove "allow-duplicates" from the trusted-types directive.', 'default-policy-not-active'); - } - status.defaultPolicyOwned = true; - if (!status.enforcementActive) { - return done('Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. ' + - 'Deliver require-trusted-types-for (header preferred).', 'enforcement-inactive'); - } - if (!sanitizerReady) { - return done('Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW ' + - '(failing closed). Bundle DOMPurify and load it before DOMFortify.', 'failing-closed'); + // Defense in depth: init() must never throw or leave the library bricked with a null status. A + // hostile getter or exotic environment that slips past the guards above fails closed here, with a + // real status object still cached and returned. + return done(`init() hit an unexpected error (${emsg(e)}); failing closed.`, 'failing-closed'); } - return done(`Active: HTML sinks sanitized, script sinks ${allowScript || allowScriptURL ? 'partly allowed by hooks' : 'refused'}.`); } function status() { return cachedStatus; diff --git a/dist/fortify.cjs.js.map b/dist/fortify.cjs.js.map index ea0cdc4..6129b03 100644 --- a/dist/fortify.cjs.js.map +++ b/dist/fortify.cjs.js.map @@ -1 +1 @@ -{"version":3,"file":"fortify.cjs.js","sources":["../src/internal.ts","../src/fortify.ts"],"sourcesContent":[null,null],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"fortify.cjs.js","sources":["../src/internal.ts","../src/fortify.ts"],"sourcesContent":[null,null],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/fortify.es.mjs b/dist/fortify.es.mjs index 5dd9143..d1aafe0 100644 --- a/dist/fortify.es.mjs +++ b/dist/fortify.es.mjs @@ -133,17 +133,37 @@ function selectOverride(options, url) { return null; for (let i = 0; i < rules.length; i++) { const r = rules[i]; - if (r && urlMatches(r.match, url)) + // Read `match` own-key only, so a polluted Object.prototype.match can't make a rule that lacks + // its own match apply to every URL. + if (r && typeof r === 'object' && urlMatches(cfg(r, 'match'), url)) { return r; + } } return null; } +// Does `raw` carry a `.sanitize` method of its own (or on its own class prototype), as opposed to one +// merely inherited from Object.prototype? We walk the chain but STOP before Object.prototype, so a +// polluted Object.prototype.sanitize is never mistaken for a real sanitizer. Class-based sanitizers, +// whose method lives on their own prototype below Object.prototype, still qualify. Tolerant of a +// hostile getter on the lookup path, which is treated as "not a sanitizer". +function looksLikeSanitizer(raw) { + try { + for (let o = raw; o && o !== Object.prototype; o = Object.getPrototypeOf(o)) { + if (own(o, 'sanitize')) + return typeof o.sanitize === 'function'; + } + } + catch { + /* a throwing getter on the chain means we cannot trust it as a sanitizer */ + } + return false; +} // Normalize whatever the caller handed us into a sanitizer with a `.sanitize` method, or null. // DOMPurify's export is itself a callable factory that ALSO carries `.sanitize`, so we must check for // `.sanitize` FIRST - otherwise we'd wrap the factory and call the wrong thing. A bare function (e.g. a // Sanitizer-API adapter) has no `.sanitize` and falls through to the function case. function resolveSanitizer(raw) { - if (raw && typeof raw.sanitize === 'function') + if (raw && looksLikeSanitizer(raw)) return raw; if (typeof raw === 'function') return { sanitize: raw }; @@ -258,84 +278,92 @@ function init(options = {}) { report(code, cachedStatus); return cachedStatus; }; - const url = loc && typeof loc.href !== 'undefined' ? String(loc.href) : ''; - // EXCLUDE: on a match, stay completely out of the way - no policy, no meta. We do NOT install a - // passthrough (that would be a silent XSS hole); under globally delivered enforcement, excluded - // pages are the developer's responsibility. Reported via status.excluded. - if (urlMatches(cfg(options, 'EXCLUDE'), url)) { - status.excluded = true; - return done('URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.', 'excluded-by-url'); - } - if (!TT || typeof TT.createPolicy !== 'function') { - return done('Trusted Types not supported; library is inert. Sinks are NOT routed.', 'tt-unsupported'); - } - // Resolve config once. `eff(key)` reads the matching URL_CONFIG rule's own key when present, else the - // base config - both own-key only. Nothing is re-read later, so runtime clobbering can't retarget - // the policy after this point either. - const override = selectOverride(options, url); - const eff = (key) => (override && own(override, key) ? override[key] : cfg(options, key)); - // INJECT_META (opt-in, best-effort - see injectMeta and the README). - if (cfg(options, 'INJECT_META') === true) { - const directive = metaDirective(cfg(options, 'META_DIRECTIVE'), typeof eff('SANITIZER') === 'function'); - status.metaInjected = injectMeta(directive); - report('meta-injection-attempted', { directive, written: status.metaInjected }); - } - status.enforcementActive = enforcementActive(); - // Sanitizer: explicit SANITIZER (possibly per-URL), else window.DOMPurify. Config is forwarded - // verbatim as the second argument, copied to drop pollution-prone keys. - let rawSan = eff('SANITIZER'); - if (rawSan === undefined) - rawSan = root.DOMPurify; - const sanitizer = resolveSanitizer(rawSan); - const rawCfg = eff('SANITIZER_CONFIG'); - const sanitizeConfig = rawCfg && typeof rawCfg === 'object' ? shallowCopy(rawCfg) : undefined; - // Sink openers count only if they're own functions, so prototype pollution can never open a sink. - const asCand = eff('ALLOW_SCRIPT'); - const asuCand = eff('ALLOW_SCRIPT_URL'); - const allowScript = typeof asCand === 'function' ? asCand : null; - const allowScriptURL = typeof asuCand === 'function' ? asuCand : null; - let sanitizerReady = false; - if (sanitizer) { - const result = smokeTest(sanitizer, sanitizeConfig); - sanitizerReady = result.ready; - if (!result.ready) - report('sanitizer-smoketest-failed', { error: result.error }); - } - status.sanitizerReady = sanitizerReady; - // createHTML closes over sanitizeConfig; the script hooks refuse unless an own-function hook allows. - const policyDef = { - createHTML: makeSanitizeHTML(sanitizer, sanitizeConfig, sanitizerReady, report), - createScript: makeScriptHook('createScript', allowScript, report), - createScriptURL: makeScriptHook('createScriptURL', allowScriptURL, report), - }; - // Did someone grab the default slot first? We can't evict them and won't vouch for them. - if (TT.defaultPolicy) { - return done('A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. ' + - 'Load DOMFortify first, inline in .', 'preexisting-default-policy'); - } - let ours; try { - ours = TT.createPolicy('default', policyDef); + const url = loc && typeof loc.href !== 'undefined' ? String(loc.href) : ''; + // EXCLUDE: on a match, stay completely out of the way - no policy, no meta. We do NOT install a + // passthrough (that would be a silent XSS hole); under globally delivered enforcement, excluded + // pages are the developer's responsibility. Reported via status.excluded. + if (urlMatches(cfg(options, 'EXCLUDE'), url)) { + status.excluded = true; + return done('URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.', 'excluded-by-url'); + } + if (!TT || typeof TT.createPolicy !== 'function') { + return done('Trusted Types not supported; library is inert. Sinks are NOT routed.', 'tt-unsupported'); + } + // Resolve config once. `eff(key)` reads the matching URL_CONFIG rule's own key when present, else the + // base config - both own-key only. Nothing is re-read later, so runtime clobbering can't retarget + // the policy after this point either. + const override = selectOverride(options, url); + const eff = (key) => (override && own(override, key) ? override[key] : cfg(options, key)); + // INJECT_META (opt-in, best-effort - see injectMeta and the README). + if (cfg(options, 'INJECT_META') === true) { + const directive = metaDirective(cfg(options, 'META_DIRECTIVE'), typeof eff('SANITIZER') === 'function'); + status.metaInjected = injectMeta(directive); + report('meta-injection-attempted', { directive, written: status.metaInjected }); + } + status.enforcementActive = enforcementActive(); + // Sanitizer: explicit SANITIZER (possibly per-URL), else window.DOMPurify. Config is forwarded + // verbatim as the second argument, copied to drop pollution-prone keys. + let rawSan = eff('SANITIZER'); + if (rawSan === undefined) + rawSan = root.DOMPurify; + const sanitizer = resolveSanitizer(rawSan); + const rawCfg = eff('SANITIZER_CONFIG'); + const sanitizeConfig = rawCfg && typeof rawCfg === 'object' ? shallowCopy(rawCfg) : undefined; + // Sink openers count only if they're own functions, so prototype pollution can never open a sink. + const asCand = eff('ALLOW_SCRIPT'); + const asuCand = eff('ALLOW_SCRIPT_URL'); + const allowScript = typeof asCand === 'function' ? asCand : null; + const allowScriptURL = typeof asuCand === 'function' ? asuCand : null; + let sanitizerReady = false; + if (sanitizer) { + const result = smokeTest(sanitizer, sanitizeConfig); + sanitizerReady = result.ready; + if (!result.ready) + report('sanitizer-smoketest-failed', { error: result.error }); + } + status.sanitizerReady = sanitizerReady; + // createHTML closes over sanitizeConfig; the script hooks refuse unless an own-function hook allows. + const policyDef = { + createHTML: makeSanitizeHTML(sanitizer, sanitizeConfig, sanitizerReady, report), + createScript: makeScriptHook('createScript', allowScript, report), + createScriptURL: makeScriptHook('createScriptURL', allowScriptURL, report), + }; + // Did someone grab the default slot first? We can't evict them and won't vouch for them. + if (TT.defaultPolicy) { + return done('A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. ' + + 'Load DOMFortify first, inline in .', 'preexisting-default-policy'); + } + let ours; + try { + ours = TT.createPolicy('default', policyDef); + } + catch (e) { + // Throws when a default policy exists and 'allow-duplicates' is off - someone won the race. + return done(`createPolicy("default") threw (${emsg(e)}); another default policy won the race.`, 'default-policy-lost'); + } + // With 'allow-duplicates' the create can succeed yet not be the active default. + if (TT.defaultPolicy && TT.defaultPolicy !== ours) { + return done('Our policy was created but is not the active default (allow-duplicates race lost). ' + + 'Remove "allow-duplicates" from the trusted-types directive.', 'default-policy-not-active'); + } + status.defaultPolicyOwned = true; + if (!status.enforcementActive) { + return done('Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. ' + + 'Deliver require-trusted-types-for (header preferred).', 'enforcement-inactive'); + } + if (!sanitizerReady) { + return done('Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW ' + + '(failing closed). Bundle DOMPurify and load it before DOMFortify.', 'failing-closed'); + } + return done(`Active: HTML sinks sanitized, script sinks ${allowScript || allowScriptURL ? 'partly allowed by hooks' : 'refused'}.`); } catch (e) { - // Throws when a default policy exists and 'allow-duplicates' is off - someone won the race. - return done(`createPolicy("default") threw (${emsg(e)}); another default policy won the race.`, 'default-policy-lost'); - } - // With 'allow-duplicates' the create can succeed yet not be the active default. - if (TT.defaultPolicy && TT.defaultPolicy !== ours) { - return done('Our policy was created but is not the active default (allow-duplicates race lost). ' + - 'Remove "allow-duplicates" from the trusted-types directive.', 'default-policy-not-active'); - } - status.defaultPolicyOwned = true; - if (!status.enforcementActive) { - return done('Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. ' + - 'Deliver require-trusted-types-for (header preferred).', 'enforcement-inactive'); - } - if (!sanitizerReady) { - return done('Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW ' + - '(failing closed). Bundle DOMPurify and load it before DOMFortify.', 'failing-closed'); + // Defense in depth: init() must never throw or leave the library bricked with a null status. A + // hostile getter or exotic environment that slips past the guards above fails closed here, with a + // real status object still cached and returned. + return done(`init() hit an unexpected error (${emsg(e)}); failing closed.`, 'failing-closed'); } - return done(`Active: HTML sinks sanitized, script sinks ${allowScript || allowScriptURL ? 'partly allowed by hooks' : 'refused'}.`); } function status() { return cachedStatus; diff --git a/dist/fortify.es.mjs.map b/dist/fortify.es.mjs.map index 0e1a0fa..ba69f28 100644 --- a/dist/fortify.es.mjs.map +++ b/dist/fortify.es.mjs.map @@ -1 +1 @@ -{"version":3,"file":"fortify.es.mjs","sources":["../src/internal.ts","../src/fortify.ts"],"sourcesContent":[null,null],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"fortify.es.mjs","sources":["../src/internal.ts","../src/fortify.ts"],"sourcesContent":[null,null],"names":[],"mappings":";AAOA;AACA,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc;AAE9C;AACM,SAAU,GAAG,CAAC,GAAY,EAAE,GAAW,EAAA;AAC3C,IAAA,OAAO,GAAG,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC;AAC7C;AAEA;AACM,SAAU,GAAG,CAAC,GAAY,EAAE,GAAW,EAAA;AAC3C,IAAA,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAI,GAA+B,CAAC,GAAG,CAAC,GAAG,SAAS;AAC1E;AAEA;AACM,SAAU,IAAI,CAAC,CAAU,EAAA;IAC7B,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;AAC/B;AAEA;AACM,SAAU,IAAI,CAAC,CAAU,EAAA;AAC7B,IAAA,OAAO,MAAM,CAAE,CAAuC,EAAE,OAAO,CAAC;AAClE;AAEA;;;AAGG;AACG,SAAU,WAAW,CAAC,GAA4B,EAAA;IACtD,MAAM,GAAG,GAA4B,EAAE;AACvC,IAAA,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE;QACnB,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,aAAa,IAAI,CAAC,KAAK,WAAW,EAAE;YACxF,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACjB;IACF;AACA,IAAA,OAAO,GAAG;AACZ;AAEA;;;;AAIG;AACG,SAAU,UAAU,CAAC,OAA8C,EAAE,GAAW,EAAA;IACpF,IAAI,OAAO,IAAI,IAAI;AAAE,QAAA,OAAO,KAAK;AACjC,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC;AACzD,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACpC,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AACjB,QAAA,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;AACzB,YAAA,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE;AAAE,gBAAA,OAAO,IAAI;QACpD;AAAO,aAAA,IAAI,CAAC,YAAY,MAAM,EAAE;AAC9B,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;AAAE,oBAAA,OAAO,IAAI;YAC9B;AAAE,YAAA,MAAM;;YAER;QACF;IACF;AACA,IAAA,OAAO,KAAK;AACd;;ACjEA;;;;;;;;;;AAUG;AAaH,MAAM,OAAO,GAAG,OAAa;AAS7B;AACA,MAAM,IAAI,GACR,OAAO,UAAU,KAAK,WAAW,GAAG,UAAU,GAAI,MAAuC;AAC3F,MAAM,GAAG,GAAyB,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,GAAG,SAAS;AACxF,MAAM,GAAG,GAAoC,IAAqD,CAAC,QAAQ;AAC3G,MAAM,EAAE,GAAI,IAAgD,CAAC,YAAY;AAEzE,IAAI,SAAS,GAAG,KAAK;AACrB,IAAI,YAAY,GAAsC,IAAI;AAE1D;AAEA;AACA;AACA,SAAS,iBAAiB,GAAA;AACxB,IAAA,IAAI;QACD,GAAgB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG;AACtD,QAAA,OAAO,KAAK;IACd;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,IAAI;IACb;AACF;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,UAAU,CAAC,OAAe,EAAA;AACjC,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,KAAK;IACtB,MAAM,CAAC,GAAG,GAAsE;IAChF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;AAC9C,IAAA,MAAM,GAAG,GAAG,sDAAsD,GAAG,IAAI,GAAG,IAAI;AAChF,IAAA,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,UAAU,EAAE;AAC/D,QAAA,IAAI;AACF,YAAA,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;AACZ,YAAA,OAAO,IAAI;QACb;AAAE,QAAA,MAAM;;QAER;IACF;AACA,IAAA,IAAI;QACF,MAAM,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC;AACjC,QAAA,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,yBAAyB,CAAC;AACvD,QAAA,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC;AAClC,QAAA,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC,CAAC;IAC9C;AAAE,IAAA,MAAM;;IAER;AACA,IAAA,OAAO,KAAK;AACd;AAEA;AAEA;AACA;AACA,SAAS,cAAc,CAAC,OAAyB,EAAE,GAAW,EAAA;IAC5D,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC;AACxC,IAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,IAAI;AACtC,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACrC,QAAA,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;;;AAGlB,QAAA,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAA0C,EAAE,GAAG,CAAC,EAAE;AAC3G,YAAA,OAAO,CAA4B;QACrC;IACF;AACA,IAAA,OAAO,IAAI;AACb;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CAAC,GAAY,EAAA;AACtC,IAAA,IAAI;QACF,KAAK,IAAI,CAAC,GAAY,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE;AACpF,YAAA,IAAI,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC;AAAE,gBAAA,OAAO,OAAQ,CAA4B,CAAC,QAAQ,KAAK,UAAU;QAC7F;IACF;AAAE,IAAA,MAAM;;IAER;AACA,IAAA,OAAO,KAAK;AACd;AAEA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CAAC,GAAY,EAAA;AACpC,IAAA,IAAI,GAAG,IAAI,kBAAkB,CAAC,GAAG,CAAC;AAAE,QAAA,OAAO,GAAgB;IAC3D,IAAI,OAAO,GAAG,KAAK,UAAU;AAAE,QAAA,OAAO,EAAE,QAAQ,EAAE,GAAiB,EAAE;AACrE,IAAA,OAAO,IAAI;AACb;AAEA;AACA;AACA,SAAS,aAAa,CAAC,EAAW,EAAE,iBAA0B,EAAA;AAC5D,IAAA,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE;AAAE,QAAA,OAAO,EAAE;IAC3C,MAAM,OAAO,GAAG,iBAAiB,GAAG,SAAS,GAAG,mBAAmB;IACnE,OAAO,CAAA,kDAAA,EAAqD,OAAO,CAAA,CAAA,CAAG;AACxE;AAEA;AACA;AACA,SAAS,SAAS,CAAC,SAAoB,EAAE,MAAe,EAAA;AACtD,IAAA,IAAI;QACF,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAClD,OAAO,OAAO,GAAG,KAAK;cAClB,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI;cAC1B,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE;IACnE;IAAE,OAAO,CAAC,EAAE;AACV,QAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE;IACzC;AACF;AAEA;AAEA;AACA;AACA;AACA,SAAS,gBAAgB,CACvB,SAA2B,EAC3B,MAAe,EACf,KAAc,EACd,MAAc,EAAA;IAEd,IAAI,OAAO,GAAG,KAAK;IACnB,OAAO,CAAC,CAAS,KAAmB;QAClC,IAAI,CAAC,KAAK,EAAE;YACV,MAAM,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC;QACd;AACA,QAAA,IAAI,OAAO;AAAE,YAAA,OAAO,CAAC;AACrB,QAAA,IAAI;YACF,OAAO,GAAG,IAAI;YACd,OAAQ,SAAuB,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAW;QAC/D;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,MAAM,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd;gBAAU;YACR,OAAO,GAAG,KAAK;QACjB;AACF,IAAA,CAAC;AACH;AAEA;AACA;AACA,SAAS,cAAc,CACrB,IAAwC,EACxC,EAAqB,EACrB,MAAc,EAAA;IAEd,OAAO,CAAC,CAAS,KAAmB;QAClC,IAAI,EAAE,EAAE;AACN,YAAA,IAAI,CAAU;AACd,YAAA,IAAI;AACF,gBAAA,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACX;YAAE,OAAO,CAAC,EAAE;AACV,gBAAA,MAAM,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3D,OAAO,IAAI,CAAC;YACd;AACA,YAAA,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;gBACzB,MAAM,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC7C,gBAAA,OAAO,CAAC;YACV;QACF;AACA,QAAA,MAAM,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9D,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;AACH;AAEA;AAEM,SAAU,IAAI,CAAC,OAAA,GAA4B,EAAE,EAAA;AACjD,IAAA,IAAI,SAAS;AAAE,QAAA,OAAO,YAA0C;IAChE,SAAS,GAAG,IAAI;;;;IAKhB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC;AACxC,IAAA,MAAM,MAAM,GACV,OAAO,GAAG,KAAK;AACb,UAAE,CAAC,IAAI,EAAE,MAAM,KAAI;AACf,YAAA,IAAI;AACD,gBAAA,GAAc,CAAC,IAAI,EAAE,MAAM,CAAC;YAC/B;AAAE,YAAA,MAAM;;YAER;QACF;AACF,UAAE,MAAK,EAAE,CAAC;AAEd,IAAA,MAAM,MAAM,GAAqB;AAC/B,QAAA,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,CAAC,CAAC,EAAE;AACjB,QAAA,iBAAiB,EAAE,KAAK;AACxB,QAAA,kBAAkB,EAAE,KAAK;AACzB,QAAA,cAAc,EAAE,KAAK;AACrB,QAAA,QAAQ,EAAE,KAAK;AACf,QAAA,YAAY,EAAE,KAAK;AACnB,QAAA,SAAS,EAAE,KAAK;AAChB,QAAA,MAAM,EAAE,EAAE;KACX;AACD,IAAA,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,IAAoB,KAAgC;AAChF,QAAA,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,kBAAkB,IAAI,MAAM,CAAC,iBAAiB,IAAI,MAAM,CAAC,cAAc;AACjG,QAAA,MAAM,CAAC,MAAM,GAAG,MAAM;;;QAGtB,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;AAC3C,QAAA,IAAI,IAAI;AAAE,YAAA,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC;AACpC,QAAA,OAAO,YAAY;AACrB,IAAA,CAAC;AAED,IAAA,IAAI;QACF,MAAM,GAAG,GAAG,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE;;;;AAK1E,QAAA,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAA0C,EAAE,GAAG,CAAC,EAAE;AACrF,YAAA,MAAM,CAAC,QAAQ,GAAG,IAAI;AACtB,YAAA,OAAO,IAAI,CAAC,yEAAyE,EAAE,iBAAiB,CAAC;QAC3G;QAEA,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,CAAC,YAAY,KAAK,UAAU,EAAE;AAChD,YAAA,OAAO,IAAI,CAAC,sEAAsE,EAAE,gBAAgB,CAAC;QACvG;;;;QAKA,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC;AAC7C,QAAA,MAAM,GAAG,GAAG,CAAC,GAAW,MAAe,QAAQ,IAAI,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;;QAG1G,IAAI,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,IAAI,EAAE;AACxC,YAAA,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,UAAU,CAAC;AACvG,YAAA,MAAM,CAAC,YAAY,GAAG,UAAU,CAAC,SAAS,CAAC;AAC3C,YAAA,MAAM,CAAC,0BAA0B,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;QACjF;AAEA,QAAA,MAAM,CAAC,iBAAiB,GAAG,iBAAiB,EAAE;;;AAI9C,QAAA,IAAI,MAAM,GAAY,GAAG,CAAC,WAAW,CAAC;QACtC,IAAI,MAAM,KAAK,SAAS;AAAE,YAAA,MAAM,GAAI,IAA2C,CAAC,SAAS;AACzF,QAAA,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC;AAC1C,QAAA,MAAM,MAAM,GAAG,GAAG,CAAC,kBAAkB,CAAC;AACtC,QAAA,MAAM,cAAc,GAClB,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,GAAG,WAAW,CAAC,MAAiC,CAAC,GAAG,SAAS;;AAGnG,QAAA,MAAM,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC;AAClC,QAAA,MAAM,OAAO,GAAG,GAAG,CAAC,kBAAkB,CAAC;AACvC,QAAA,MAAM,WAAW,GAAG,OAAO,MAAM,KAAK,UAAU,GAAI,MAAqB,GAAG,IAAI;AAChF,QAAA,MAAM,cAAc,GAAG,OAAO,OAAO,KAAK,UAAU,GAAI,OAAsB,GAAG,IAAI;QAErF,IAAI,cAAc,GAAG,KAAK;QAC1B,IAAI,SAAS,EAAE;YACb,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC;AACnD,YAAA,cAAc,GAAG,MAAM,CAAC,KAAK;YAC7B,IAAI,CAAC,MAAM,CAAC,KAAK;gBAAE,MAAM,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAClF;AACA,QAAA,MAAM,CAAC,cAAc,GAAG,cAAc;;AAGtC,QAAA,MAAM,SAAS,GAAG;YAChB,UAAU,EAAE,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,CAAC;YAC/E,YAAY,EAAE,cAAc,CAAC,cAAc,EAAE,WAAW,EAAE,MAAM,CAAC;YACjE,eAAe,EAAE,cAAc,CAAC,iBAAiB,EAAE,cAAc,EAAE,MAAM,CAAC;SAC3E;;AAGD,QAAA,IAAI,EAAE,CAAC,aAAa,EAAE;YACpB,OAAO,IAAI,CACT,qGAAqG;gBACnG,0CAA0C,EAC5C,4BAA4B,CAC7B;QACH;AAEA,QAAA,IAAI,IAAa;AACjB,QAAA,IAAI;YACF,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC;QAC9C;QAAE,OAAO,CAAC,EAAE;;YAEV,OAAO,IAAI,CACT,CAAA,+BAAA,EAAkC,IAAI,CAAC,CAAC,CAAC,CAAA,uCAAA,CAAyC,EAClF,qBAAqB,CACtB;QACH;;QAGA,IAAI,EAAE,CAAC,aAAa,IAAI,EAAE,CAAC,aAAa,KAAK,IAAI,EAAE;YACjD,OAAO,IAAI,CACT,qFAAqF;gBACnF,6DAA6D,EAC/D,2BAA2B,CAC5B;QACH;AAEA,QAAA,MAAM,CAAC,kBAAkB,GAAG,IAAI;AAEhC,QAAA,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE;YAC7B,OAAO,IAAI,CACT,qGAAqG;gBACnG,uDAAuD,EACzD,sBAAsB,CACvB;QACH;QACA,IAAI,CAAC,cAAc,EAAE;YACnB,OAAO,IAAI,CACT,+FAA+F;gBAC7F,mEAAmE,EACrE,gBAAgB,CACjB;QACH;AACA,QAAA,OAAO,IAAI,CACT,CAAA,2CAAA,EAA8C,WAAW,IAAI,cAAc,GAAG,yBAAyB,GAAG,SAAS,CAAA,CAAA,CAAG,CACvH;IACH;IAAE,OAAO,CAAC,EAAE;;;;QAIV,OAAO,IAAI,CAAC,CAAA,gCAAA,EAAmC,IAAI,CAAC,CAAC,CAAC,CAAA,kBAAA,CAAoB,EAAE,gBAAgB,CAAC;IAC/F;AACF;SAEgB,MAAM,GAAA;AACpB,IAAA,OAAO,YAAY;AACrB;AAEO,MAAM,UAAU,GAAkB,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;;;;"} \ No newline at end of file diff --git a/dist/fortify.js b/dist/fortify.js index 99cd7aa..eba0fbd 100644 --- a/dist/fortify.js +++ b/dist/fortify.js @@ -136,17 +136,37 @@ return null; for (let i = 0; i < rules.length; i++) { const r = rules[i]; - if (r && urlMatches(r.match, url)) + // Read `match` own-key only, so a polluted Object.prototype.match can't make a rule that lacks + // its own match apply to every URL. + if (r && typeof r === 'object' && urlMatches(cfg(r, 'match'), url)) { return r; + } } return null; } + // Does `raw` carry a `.sanitize` method of its own (or on its own class prototype), as opposed to one + // merely inherited from Object.prototype? We walk the chain but STOP before Object.prototype, so a + // polluted Object.prototype.sanitize is never mistaken for a real sanitizer. Class-based sanitizers, + // whose method lives on their own prototype below Object.prototype, still qualify. Tolerant of a + // hostile getter on the lookup path, which is treated as "not a sanitizer". + function looksLikeSanitizer(raw) { + try { + for (let o = raw; o && o !== Object.prototype; o = Object.getPrototypeOf(o)) { + if (own(o, 'sanitize')) + return typeof o.sanitize === 'function'; + } + } + catch { + /* a throwing getter on the chain means we cannot trust it as a sanitizer */ + } + return false; + } // Normalize whatever the caller handed us into a sanitizer with a `.sanitize` method, or null. // DOMPurify's export is itself a callable factory that ALSO carries `.sanitize`, so we must check for // `.sanitize` FIRST - otherwise we'd wrap the factory and call the wrong thing. A bare function (e.g. a // Sanitizer-API adapter) has no `.sanitize` and falls through to the function case. function resolveSanitizer(raw) { - if (raw && typeof raw.sanitize === 'function') + if (raw && looksLikeSanitizer(raw)) return raw; if (typeof raw === 'function') return { sanitize: raw }; @@ -261,84 +281,92 @@ report(code, cachedStatus); return cachedStatus; }; - const url = loc && typeof loc.href !== 'undefined' ? String(loc.href) : ''; - // EXCLUDE: on a match, stay completely out of the way - no policy, no meta. We do NOT install a - // passthrough (that would be a silent XSS hole); under globally delivered enforcement, excluded - // pages are the developer's responsibility. Reported via status.excluded. - if (urlMatches(cfg(options, 'EXCLUDE'), url)) { - status.excluded = true; - return done('URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.', 'excluded-by-url'); - } - if (!TT || typeof TT.createPolicy !== 'function') { - return done('Trusted Types not supported; library is inert. Sinks are NOT routed.', 'tt-unsupported'); - } - // Resolve config once. `eff(key)` reads the matching URL_CONFIG rule's own key when present, else the - // base config - both own-key only. Nothing is re-read later, so runtime clobbering can't retarget - // the policy after this point either. - const override = selectOverride(options, url); - const eff = (key) => (override && own(override, key) ? override[key] : cfg(options, key)); - // INJECT_META (opt-in, best-effort - see injectMeta and the README). - if (cfg(options, 'INJECT_META') === true) { - const directive = metaDirective(cfg(options, 'META_DIRECTIVE'), typeof eff('SANITIZER') === 'function'); - status.metaInjected = injectMeta(directive); - report('meta-injection-attempted', { directive, written: status.metaInjected }); - } - status.enforcementActive = enforcementActive(); - // Sanitizer: explicit SANITIZER (possibly per-URL), else window.DOMPurify. Config is forwarded - // verbatim as the second argument, copied to drop pollution-prone keys. - let rawSan = eff('SANITIZER'); - if (rawSan === undefined) - rawSan = root.DOMPurify; - const sanitizer = resolveSanitizer(rawSan); - const rawCfg = eff('SANITIZER_CONFIG'); - const sanitizeConfig = rawCfg && typeof rawCfg === 'object' ? shallowCopy(rawCfg) : undefined; - // Sink openers count only if they're own functions, so prototype pollution can never open a sink. - const asCand = eff('ALLOW_SCRIPT'); - const asuCand = eff('ALLOW_SCRIPT_URL'); - const allowScript = typeof asCand === 'function' ? asCand : null; - const allowScriptURL = typeof asuCand === 'function' ? asuCand : null; - let sanitizerReady = false; - if (sanitizer) { - const result = smokeTest(sanitizer, sanitizeConfig); - sanitizerReady = result.ready; - if (!result.ready) - report('sanitizer-smoketest-failed', { error: result.error }); - } - status.sanitizerReady = sanitizerReady; - // createHTML closes over sanitizeConfig; the script hooks refuse unless an own-function hook allows. - const policyDef = { - createHTML: makeSanitizeHTML(sanitizer, sanitizeConfig, sanitizerReady, report), - createScript: makeScriptHook('createScript', allowScript, report), - createScriptURL: makeScriptHook('createScriptURL', allowScriptURL, report), - }; - // Did someone grab the default slot first? We can't evict them and won't vouch for them. - if (TT.defaultPolicy) { - return done('A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. ' + - 'Load DOMFortify first, inline in .', 'preexisting-default-policy'); - } - let ours; try { - ours = TT.createPolicy('default', policyDef); + const url = loc && typeof loc.href !== 'undefined' ? String(loc.href) : ''; + // EXCLUDE: on a match, stay completely out of the way - no policy, no meta. We do NOT install a + // passthrough (that would be a silent XSS hole); under globally delivered enforcement, excluded + // pages are the developer's responsibility. Reported via status.excluded. + if (urlMatches(cfg(options, 'EXCLUDE'), url)) { + status.excluded = true; + return done('URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.', 'excluded-by-url'); + } + if (!TT || typeof TT.createPolicy !== 'function') { + return done('Trusted Types not supported; library is inert. Sinks are NOT routed.', 'tt-unsupported'); + } + // Resolve config once. `eff(key)` reads the matching URL_CONFIG rule's own key when present, else the + // base config - both own-key only. Nothing is re-read later, so runtime clobbering can't retarget + // the policy after this point either. + const override = selectOverride(options, url); + const eff = (key) => (override && own(override, key) ? override[key] : cfg(options, key)); + // INJECT_META (opt-in, best-effort - see injectMeta and the README). + if (cfg(options, 'INJECT_META') === true) { + const directive = metaDirective(cfg(options, 'META_DIRECTIVE'), typeof eff('SANITIZER') === 'function'); + status.metaInjected = injectMeta(directive); + report('meta-injection-attempted', { directive, written: status.metaInjected }); + } + status.enforcementActive = enforcementActive(); + // Sanitizer: explicit SANITIZER (possibly per-URL), else window.DOMPurify. Config is forwarded + // verbatim as the second argument, copied to drop pollution-prone keys. + let rawSan = eff('SANITIZER'); + if (rawSan === undefined) + rawSan = root.DOMPurify; + const sanitizer = resolveSanitizer(rawSan); + const rawCfg = eff('SANITIZER_CONFIG'); + const sanitizeConfig = rawCfg && typeof rawCfg === 'object' ? shallowCopy(rawCfg) : undefined; + // Sink openers count only if they're own functions, so prototype pollution can never open a sink. + const asCand = eff('ALLOW_SCRIPT'); + const asuCand = eff('ALLOW_SCRIPT_URL'); + const allowScript = typeof asCand === 'function' ? asCand : null; + const allowScriptURL = typeof asuCand === 'function' ? asuCand : null; + let sanitizerReady = false; + if (sanitizer) { + const result = smokeTest(sanitizer, sanitizeConfig); + sanitizerReady = result.ready; + if (!result.ready) + report('sanitizer-smoketest-failed', { error: result.error }); + } + status.sanitizerReady = sanitizerReady; + // createHTML closes over sanitizeConfig; the script hooks refuse unless an own-function hook allows. + const policyDef = { + createHTML: makeSanitizeHTML(sanitizer, sanitizeConfig, sanitizerReady, report), + createScript: makeScriptHook('createScript', allowScript, report), + createScriptURL: makeScriptHook('createScriptURL', allowScriptURL, report), + }; + // Did someone grab the default slot first? We can't evict them and won't vouch for them. + if (TT.defaultPolicy) { + return done('A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. ' + + 'Load DOMFortify first, inline in .', 'preexisting-default-policy'); + } + let ours; + try { + ours = TT.createPolicy('default', policyDef); + } + catch (e) { + // Throws when a default policy exists and 'allow-duplicates' is off - someone won the race. + return done(`createPolicy("default") threw (${emsg(e)}); another default policy won the race.`, 'default-policy-lost'); + } + // With 'allow-duplicates' the create can succeed yet not be the active default. + if (TT.defaultPolicy && TT.defaultPolicy !== ours) { + return done('Our policy was created but is not the active default (allow-duplicates race lost). ' + + 'Remove "allow-duplicates" from the trusted-types directive.', 'default-policy-not-active'); + } + status.defaultPolicyOwned = true; + if (!status.enforcementActive) { + return done('Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. ' + + 'Deliver require-trusted-types-for (header preferred).', 'enforcement-inactive'); + } + if (!sanitizerReady) { + return done('Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW ' + + '(failing closed). Bundle DOMPurify and load it before DOMFortify.', 'failing-closed'); + } + return done(`Active: HTML sinks sanitized, script sinks ${allowScript || allowScriptURL ? 'partly allowed by hooks' : 'refused'}.`); } catch (e) { - // Throws when a default policy exists and 'allow-duplicates' is off - someone won the race. - return done(`createPolicy("default") threw (${emsg(e)}); another default policy won the race.`, 'default-policy-lost'); - } - // With 'allow-duplicates' the create can succeed yet not be the active default. - if (TT.defaultPolicy && TT.defaultPolicy !== ours) { - return done('Our policy was created but is not the active default (allow-duplicates race lost). ' + - 'Remove "allow-duplicates" from the trusted-types directive.', 'default-policy-not-active'); - } - status.defaultPolicyOwned = true; - if (!status.enforcementActive) { - return done('Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. ' + - 'Deliver require-trusted-types-for (header preferred).', 'enforcement-inactive'); - } - if (!sanitizerReady) { - return done('Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW ' + - '(failing closed). Bundle DOMPurify and load it before DOMFortify.', 'failing-closed'); + // Defense in depth: init() must never throw or leave the library bricked with a null status. A + // hostile getter or exotic environment that slips past the guards above fails closed here, with a + // real status object still cached and returned. + return done(`init() hit an unexpected error (${emsg(e)}); failing closed.`, 'failing-closed'); } - return done(`Active: HTML sinks sanitized, script sinks ${allowScript || allowScriptURL ? 'partly allowed by hooks' : 'refused'}.`); } function status() { return cachedStatus; diff --git a/dist/fortify.js.map b/dist/fortify.js.map index 9cf196e..5372928 100644 --- a/dist/fortify.js.map +++ b/dist/fortify.js.map @@ -1 +1 @@ -{"version":3,"file":"fortify.js","sources":["../src/internal.ts","../src/fortify.ts","../src/auto.ts"],"sourcesContent":[null,null,null],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"fortify.js","sources":["../src/internal.ts","../src/fortify.ts","../src/auto.ts"],"sourcesContent":[null,null,null],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/fortify.min.js b/dist/fortify.min.js index b56e0a1..65c8020 100644 --- a/dist/fortify.min.js +++ b/dist/fortify.min.js @@ -1,3 +1,3 @@ /*! DOMFortify 0.2.0 | (c) Cure53 and contributors | (MPL-2.0 OR Apache-2.0) */ -!function(){"use strict";const t=Object.prototype.hasOwnProperty;function e(e,r){return null!=e&&t.call(e,r)}function r(t,r){return e(t,r)?t[r]:void 0}function n(t){return String(t).slice(0,80)}function i(t){return String(t?.message)}function o(t,e){if(null==t)return!1;const r=Array.isArray(t)?t:[t];for(let t=0;t{if(!r)return n("sanitizer-unavailable",{sink:"createHTML"}),null;if(o)return c;try{return o=!0,t.sanitize(c,e)}catch(t){return n("sanitize-threw",{error:i(t)}),null}finally{o=!1}}}function y(t,e,r){return o=>{if(e){let n;try{n=e(o)}catch(e){return r("script-hook-threw",{sink:t,error:i(e)}),null}if("string"==typeof n)return r("script-sink-allowed",{sink:t}),n}return r("script-sink-refused",{sink:t,sample:n(o)}),null}}const p=Object.freeze({init:function(n={}){if(s)return f;s=!0;const p=r(n,"ON_VIOLATION"),h="function"==typeof p?(t,e)=>{try{p(t,e)}catch{}}:()=>{},v={version:"0.2.0",ttSupported:!!l,enforcementActive:!1,defaultPolicyOwned:!1,sanitizerReady:!1,excluded:!1,metaInjected:!1,protected:!1,reason:""},m=(t,e)=>(v.protected=v.defaultPolicyOwned&&v.enforcementActive&&v.sanitizerReady,v.reason=t,f=Object.freeze({...v}),e&&h(e,f),f),O=u&&void 0!==u.href?String(u.href):"";if(o(r(n,"EXCLUDE"),O))return v.excluded=!0,m("URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.","excluded-by-url");if(!l||"function"!=typeof l.createPolicy)return m("Trusted Types not supported; library is inert. Sinks are NOT routed.","tt-unsupported");const T=function(t,e){const n=r(t,"URL_CONFIG");if(!Array.isArray(n))return null;for(let t=0;tT&&e(T,t)?T[t]:r(n,t);if(!0===r(n,"INJECT_META")){const t=(g=r(n,"META_DIRECTIVE"),A="function"==typeof w("SANITIZER"),"string"==typeof g&&g?g:`require-trusted-types-for 'script'; trusted-types ${A?"default":"default dompurify"};`);v.metaInjected=function(t){if(!a)return!1;const e=a,r='\r\n]/g,"")+'">';if("loading"===e.readyState&&"function"==typeof e.write)try{return e.write(r),!0}catch{}try{const r=e.createElement("meta");r.setAttribute("http-equiv","Content-Security-Policy"),r.setAttribute("content",t),(e.head||e.documentElement).appendChild(r)}catch{}return!1}(t),h("meta-injection-attempted",{directive:t,written:v.metaInjected})}var g,A;v.enforcementActive=function(){try{return a.createElement("div").innerHTML="x",!1}catch{return!0}}();let b=w("SANITIZER");void 0===b&&(b=c.DOMPurify);const I=(L=b)&&"function"==typeof L.sanitize?L:"function"==typeof L?{sanitize:L}:null;var L;const E=w("SANITIZER_CONFIG"),R=E&&"object"==typeof E?function(e){const r={};for(const n in e)t.call(e,n)&&"__proto__"!==n&&"constructor"!==n&&"prototype"!==n&&(r[n]=e[n]);return r}(E):void 0,S=w("ALLOW_SCRIPT"),k=w("ALLOW_SCRIPT_URL"),P="function"==typeof S?S:null,z="function"==typeof k?k:null;let M=!1;if(I){const t=function(t,e){try{return"string"==typeof t.sanitize("x",e)?{ready:!0,error:null}:{ready:!1,error:"sanitize() did not return a string"}}catch(t){return{ready:!1,error:i(t)}}}(I,R);M=t.ready,t.ready||h("sanitizer-smoketest-failed",{error:t.error})}v.sanitizerReady=M;const D={createHTML:d(I,R,M,h),createScript:y("createScript",P,h),createScriptURL:y("createScriptURL",z,h)};if(l.defaultPolicy)return m("A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. Load DOMFortify first, inline in .","preexisting-default-policy");let C;try{C=l.createPolicy("default",D)}catch(t){return m(`createPolicy("default") threw (${i(t)}); another default policy won the race.`,"default-policy-lost")}return l.defaultPolicy&&l.defaultPolicy!==C?m('Our policy was created but is not the active default (allow-duplicates race lost). Remove "allow-duplicates" from the trusted-types directive.',"default-policy-not-active"):(v.defaultPolicyOwned=!0,v.enforcementActive?M?m(`Active: HTML sinks sanitized, script sinks ${P||z?"partly allowed by hooks":"refused"}.`):m("Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW (failing closed). Bundle DOMPurify and load it before DOMFortify.","failing-closed"):m("Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. Deliver require-trusted-types-for (header preferred).","enforcement-inactive"))},status:function(){return f}});"undefined"!=typeof window&&(window.DOMFortify=p,p.init(window.DOMFortifyConfig||{}))}(); +!function(){"use strict";const t=Object.prototype.hasOwnProperty;function e(e,r){return null!=e&&t.call(e,r)}function r(t,r){return e(t,r)?t[r]:void 0}function n(t){return String(t).slice(0,80)}function i(t){return String(t?.message)}function o(t,e){if(null==t)return!1;const r=Array.isArray(t)?t:[t];for(let t=0;t{if(!r)return n("sanitizer-unavailable",{sink:"createHTML"}),null;if(o)return c;try{return o=!0,t.sanitize(c,e)}catch(t){return n("sanitize-threw",{error:i(t)}),null}finally{o=!1}}}function p(t,e,r){return o=>{if(e){let n;try{n=e(o)}catch(e){return r("script-hook-threw",{sink:t,error:i(e)}),null}if("string"==typeof n)return r("script-sink-allowed",{sink:t}),n}return r("script-sink-refused",{sink:t,sample:n(o)}),null}}const h=Object.freeze({init:function(n={}){if(f)return s;f=!0;const h=r(n,"ON_VIOLATION"),O="function"==typeof h?(t,e)=>{try{h(t,e)}catch{}}:()=>{},m={version:"0.2.0",ttSupported:!!l,enforcementActive:!1,defaultPolicyOwned:!1,sanitizerReady:!1,excluded:!1,metaInjected:!1,protected:!1,reason:""},v=(t,e)=>(m.protected=m.defaultPolicyOwned&&m.enforcementActive&&m.sanitizerReady,m.reason=t,s=Object.freeze({...m}),e&&O(e,s),s);try{const f=a&&void 0!==a.href?String(a.href):"";if(o(r(n,"EXCLUDE"),f))return m.excluded=!0,v("URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.","excluded-by-url");if(!l||"function"!=typeof l.createPolicy)return v("Trusted Types not supported; library is inert. Sinks are NOT routed.","tt-unsupported");const s=function(t,e){const n=r(t,"URL_CONFIG");if(!Array.isArray(n))return null;for(let t=0;ts&&e(s,t)?s[t]:r(n,t);if(!0===r(n,"INJECT_META")){const t=(T=r(n,"META_DIRECTIVE"),w="function"==typeof h("SANITIZER"),"string"==typeof T&&T?T:`require-trusted-types-for 'script'; trusted-types ${w?"default":"default dompurify"};`);m.metaInjected=function(t){if(!u)return!1;const e=u,r='\r\n]/g,"")+'">';if("loading"===e.readyState&&"function"==typeof e.write)try{return e.write(r),!0}catch{}try{const r=e.createElement("meta");r.setAttribute("http-equiv","Content-Security-Policy"),r.setAttribute("content",t),(e.head||e.documentElement).appendChild(r)}catch{}return!1}(t),O("meta-injection-attempted",{directive:t,written:m.metaInjected})}m.enforcementActive=function(){try{return u.createElement("div").innerHTML="x",!1}catch{return!0}}();let g=h("SANITIZER");void 0===g&&(g=c.DOMPurify);const b=d(g),A=h("SANITIZER_CONFIG"),I=A&&"object"==typeof A?function(e){const r={};for(const n in e)t.call(e,n)&&"__proto__"!==n&&"constructor"!==n&&"prototype"!==n&&(r[n]=e[n]);return r}(A):void 0,L=h("ALLOW_SCRIPT"),E=h("ALLOW_SCRIPT_URL"),P="function"==typeof L?L:null,R="function"==typeof E?E:null;let S=!1;if(b){const t=function(t,e){try{return"string"==typeof t.sanitize("x",e)?{ready:!0,error:null}:{ready:!1,error:"sanitize() did not return a string"}}catch(t){return{ready:!1,error:i(t)}}}(b,I);S=t.ready,t.ready||O("sanitizer-smoketest-failed",{error:t.error})}m.sanitizerReady=S;const k={createHTML:y(b,I,S,O),createScript:p("createScript",P,O),createScriptURL:p("createScriptURL",R,O)};if(l.defaultPolicy)return v("A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. Load DOMFortify first, inline in .","preexisting-default-policy");let z;try{z=l.createPolicy("default",k)}catch(t){return v(`createPolicy("default") threw (${i(t)}); another default policy won the race.`,"default-policy-lost")}return l.defaultPolicy&&l.defaultPolicy!==z?v('Our policy was created but is not the active default (allow-duplicates race lost). Remove "allow-duplicates" from the trusted-types directive.',"default-policy-not-active"):(m.defaultPolicyOwned=!0,m.enforcementActive?S?v(`Active: HTML sinks sanitized, script sinks ${P||R?"partly allowed by hooks":"refused"}.`):v("Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW (failing closed). Bundle DOMPurify and load it before DOMFortify.","failing-closed"):v("Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. Deliver require-trusted-types-for (header preferred).","enforcement-inactive"))}catch(t){return v(`init() hit an unexpected error (${i(t)}); failing closed.`,"failing-closed")}var T,w},status:function(){return s}});"undefined"!=typeof window&&(window.DOMFortify=h,h.init(window.DOMFortifyConfig||{}))}(); //# sourceMappingURL=fortify.min.js.map diff --git a/dist/fortify.min.js.map b/dist/fortify.min.js.map index fd13b41..ac31a39 100644 --- a/dist/fortify.min.js.map +++ b/dist/fortify.min.js.map @@ -1 +1 @@ -{"version":3,"file":"fortify.min.js","sources":["../src/internal.ts","../src/fortify.ts","../src/auto.ts"],"sourcesContent":[null,null,null],"names":["hasOwn","Object","prototype","hasOwnProperty","own","obj","key","call","cfg","undefined","clip","s","String","slice","emsg","e","message","urlMatches","pattern","url","list","Array","isArray","i","length","p","indexOf","RegExp","test","root","globalThis","window","doc","document","loc","location","TT","trustedTypes","installed","cachedStatus","makeSanitizeHTML","sanitizer","config","ready","report","reentry","sink","sanitize","error","makeScriptHook","kind","fn","r","sample","DOMFortify","freeze","init","options","onv","code","detail","status","version","ttSupported","enforcementActive","defaultPolicyOwned","sanitizerReady","excluded","metaInjected","protected","reason","done","href","createPolicy","override","rules","match","selectOverride","eff","directive","md","functionSanitizer","content","d","tag","replace","readyState","write","m","createElement","setAttribute","head","documentElement","appendChild","injectMeta","written","innerHTML","rawSan","DOMPurify","raw","rawCfg","sanitizeConfig","out","k","shallowCopy","asCand","asuCand","allowScript","allowScriptURL","result","smokeTest","policyDef","createHTML","createScript","createScriptURL","defaultPolicy","ours","DOMFortifyConfig"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"fortify.min.js","sources":["../src/internal.ts","../src/fortify.ts","../src/auto.ts"],"sourcesContent":[null,null,null],"names":["hasOwn","Object","prototype","hasOwnProperty","own","obj","key","call","cfg","undefined","clip","s","String","slice","emsg","e","message","urlMatches","pattern","url","list","Array","isArray","i","length","p","indexOf","RegExp","test","root","globalThis","window","doc","document","loc","location","TT","trustedTypes","installed","cachedStatus","resolveSanitizer","raw","o","getPrototypeOf","sanitize","looksLikeSanitizer","makeSanitizeHTML","sanitizer","config","ready","report","reentry","sink","error","makeScriptHook","kind","fn","r","sample","DOMFortify","freeze","init","options","onv","code","detail","status","version","ttSupported","enforcementActive","defaultPolicyOwned","sanitizerReady","excluded","metaInjected","protected","reason","done","href","createPolicy","override","rules","selectOverride","eff","directive","md","functionSanitizer","content","d","tag","replace","readyState","write","m","createElement","setAttribute","head","documentElement","appendChild","injectMeta","written","innerHTML","rawSan","DOMPurify","rawCfg","sanitizeConfig","out","k","shallowCopy","asCand","asuCand","allowScript","allowScriptURL","result","smokeTest","policyDef","createHTML","createScript","createScriptURL","defaultPolicy","ours","DOMFortifyConfig"],"mappings":"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"} \ No newline at end of file diff --git a/src/fortify.ts b/src/fortify.ts index a1e851f..44640cf 100644 --- a/src/fortify.ts +++ b/src/fortify.ts @@ -17,7 +17,6 @@ import type { Sanitizer, SanitizeFn, ScriptHook, - UrlConfigRule, UrlPattern, ViolationCode, } from './types'; @@ -95,18 +94,38 @@ function selectOverride(options: DOMFortifyConfig, url: string): Record; + const r = rules[i]; + // Read `match` own-key only, so a polluted Object.prototype.match can't make a rule that lacks + // its own match apply to every URL. + if (r && typeof r === 'object' && urlMatches(cfg(r, 'match') as UrlPattern | UrlPattern[] | undefined, url)) { + return r as Record; + } } return null; } +// Does `raw` carry a `.sanitize` method of its own (or on its own class prototype), as opposed to one +// merely inherited from Object.prototype? We walk the chain but STOP before Object.prototype, so a +// polluted Object.prototype.sanitize is never mistaken for a real sanitizer. Class-based sanitizers, +// whose method lives on their own prototype below Object.prototype, still qualify. Tolerant of a +// hostile getter on the lookup path, which is treated as "not a sanitizer". +function looksLikeSanitizer(raw: unknown): boolean { + try { + for (let o: unknown = raw; o && o !== Object.prototype; o = Object.getPrototypeOf(o)) { + if (own(o, 'sanitize')) return typeof (o as { sanitize?: unknown }).sanitize === 'function'; + } + } catch { + /* a throwing getter on the chain means we cannot trust it as a sanitizer */ + } + return false; +} + // Normalize whatever the caller handed us into a sanitizer with a `.sanitize` method, or null. // DOMPurify's export is itself a callable factory that ALSO carries `.sanitize`, so we must check for // `.sanitize` FIRST - otherwise we'd wrap the factory and call the wrong thing. A bare function (e.g. a // Sanitizer-API adapter) has no `.sanitize` and falls through to the function case. function resolveSanitizer(raw: unknown): Sanitizer | null { - if (raw && typeof (raw as Sanitizer).sanitize === 'function') return raw as Sanitizer; + if (raw && looksLikeSanitizer(raw)) return raw as Sanitizer; if (typeof raw === 'function') return { sanitize: raw as SanitizeFn }; return null; } @@ -230,113 +249,120 @@ export function init(options: DOMFortifyConfig = {}): Readonly return cachedStatus; }; - const url = loc && typeof loc.href !== 'undefined' ? String(loc.href) : ''; - - // EXCLUDE: on a match, stay completely out of the way - no policy, no meta. We do NOT install a - // passthrough (that would be a silent XSS hole); under globally delivered enforcement, excluded - // pages are the developer's responsibility. Reported via status.excluded. - if (urlMatches(cfg(options, 'EXCLUDE') as UrlPattern | UrlPattern[] | undefined, url)) { - status.excluded = true; - return done('URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.', 'excluded-by-url'); - } - - if (!TT || typeof TT.createPolicy !== 'function') { - return done('Trusted Types not supported; library is inert. Sinks are NOT routed.', 'tt-unsupported'); - } - - // Resolve config once. `eff(key)` reads the matching URL_CONFIG rule's own key when present, else the - // base config - both own-key only. Nothing is re-read later, so runtime clobbering can't retarget - // the policy after this point either. - const override = selectOverride(options, url); - const eff = (key: string): unknown => (override && own(override, key) ? override[key] : cfg(options, key)); - - // INJECT_META (opt-in, best-effort - see injectMeta and the README). - if (cfg(options, 'INJECT_META') === true) { - const directive = metaDirective(cfg(options, 'META_DIRECTIVE'), typeof eff('SANITIZER') === 'function'); - status.metaInjected = injectMeta(directive); - report('meta-injection-attempted', { directive, written: status.metaInjected }); - } + try { + const url = loc && typeof loc.href !== 'undefined' ? String(loc.href) : ''; + + // EXCLUDE: on a match, stay completely out of the way - no policy, no meta. We do NOT install a + // passthrough (that would be a silent XSS hole); under globally delivered enforcement, excluded + // pages are the developer's responsibility. Reported via status.excluded. + if (urlMatches(cfg(options, 'EXCLUDE') as UrlPattern | UrlPattern[] | undefined, url)) { + status.excluded = true; + return done('URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.', 'excluded-by-url'); + } - status.enforcementActive = enforcementActive(); - - // Sanitizer: explicit SANITIZER (possibly per-URL), else window.DOMPurify. Config is forwarded - // verbatim as the second argument, copied to drop pollution-prone keys. - let rawSan: unknown = eff('SANITIZER'); - if (rawSan === undefined) rawSan = (root as unknown as { DOMPurify?: unknown }).DOMPurify; - const sanitizer = resolveSanitizer(rawSan); - const rawCfg = eff('SANITIZER_CONFIG'); - const sanitizeConfig = - rawCfg && typeof rawCfg === 'object' ? shallowCopy(rawCfg as Record) : undefined; - - // Sink openers count only if they're own functions, so prototype pollution can never open a sink. - const asCand = eff('ALLOW_SCRIPT'); - const asuCand = eff('ALLOW_SCRIPT_URL'); - const allowScript = typeof asCand === 'function' ? (asCand as ScriptHook) : null; - const allowScriptURL = typeof asuCand === 'function' ? (asuCand as ScriptHook) : null; - - let sanitizerReady = false; - if (sanitizer) { - const result = smokeTest(sanitizer, sanitizeConfig); - sanitizerReady = result.ready; - if (!result.ready) report('sanitizer-smoketest-failed', { error: result.error }); - } - status.sanitizerReady = sanitizerReady; + if (!TT || typeof TT.createPolicy !== 'function') { + return done('Trusted Types not supported; library is inert. Sinks are NOT routed.', 'tt-unsupported'); + } - // createHTML closes over sanitizeConfig; the script hooks refuse unless an own-function hook allows. - const policyDef = { - createHTML: makeSanitizeHTML(sanitizer, sanitizeConfig, sanitizerReady, report), - createScript: makeScriptHook('createScript', allowScript, report), - createScriptURL: makeScriptHook('createScriptURL', allowScriptURL, report), - }; + // Resolve config once. `eff(key)` reads the matching URL_CONFIG rule's own key when present, else the + // base config - both own-key only. Nothing is re-read later, so runtime clobbering can't retarget + // the policy after this point either. + const override = selectOverride(options, url); + const eff = (key: string): unknown => (override && own(override, key) ? override[key] : cfg(options, key)); + + // INJECT_META (opt-in, best-effort - see injectMeta and the README). + if (cfg(options, 'INJECT_META') === true) { + const directive = metaDirective(cfg(options, 'META_DIRECTIVE'), typeof eff('SANITIZER') === 'function'); + status.metaInjected = injectMeta(directive); + report('meta-injection-attempted', { directive, written: status.metaInjected }); + } - // Did someone grab the default slot first? We can't evict them and won't vouch for them. - if (TT.defaultPolicy) { - return done( - 'A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. ' + - 'Load DOMFortify first, inline in .', - 'preexisting-default-policy', - ); - } + status.enforcementActive = enforcementActive(); + + // Sanitizer: explicit SANITIZER (possibly per-URL), else window.DOMPurify. Config is forwarded + // verbatim as the second argument, copied to drop pollution-prone keys. + let rawSan: unknown = eff('SANITIZER'); + if (rawSan === undefined) rawSan = (root as unknown as { DOMPurify?: unknown }).DOMPurify; + const sanitizer = resolveSanitizer(rawSan); + const rawCfg = eff('SANITIZER_CONFIG'); + const sanitizeConfig = + rawCfg && typeof rawCfg === 'object' ? shallowCopy(rawCfg as Record) : undefined; + + // Sink openers count only if they're own functions, so prototype pollution can never open a sink. + const asCand = eff('ALLOW_SCRIPT'); + const asuCand = eff('ALLOW_SCRIPT_URL'); + const allowScript = typeof asCand === 'function' ? (asCand as ScriptHook) : null; + const allowScriptURL = typeof asuCand === 'function' ? (asuCand as ScriptHook) : null; + + let sanitizerReady = false; + if (sanitizer) { + const result = smokeTest(sanitizer, sanitizeConfig); + sanitizerReady = result.ready; + if (!result.ready) report('sanitizer-smoketest-failed', { error: result.error }); + } + status.sanitizerReady = sanitizerReady; + + // createHTML closes over sanitizeConfig; the script hooks refuse unless an own-function hook allows. + const policyDef = { + createHTML: makeSanitizeHTML(sanitizer, sanitizeConfig, sanitizerReady, report), + createScript: makeScriptHook('createScript', allowScript, report), + createScriptURL: makeScriptHook('createScriptURL', allowScriptURL, report), + }; + + // Did someone grab the default slot first? We can't evict them and won't vouch for them. + if (TT.defaultPolicy) { + return done( + 'A default Trusted Types policy already exists; DOMFortify did NOT install and cannot vouch for it. ' + + 'Load DOMFortify first, inline in .', + 'preexisting-default-policy', + ); + } - let ours: unknown; - try { - ours = TT.createPolicy('default', policyDef); - } catch (e) { - // Throws when a default policy exists and 'allow-duplicates' is off - someone won the race. - return done( - `createPolicy("default") threw (${emsg(e)}); another default policy won the race.`, - 'default-policy-lost', - ); - } + let ours: unknown; + try { + ours = TT.createPolicy('default', policyDef); + } catch (e) { + // Throws when a default policy exists and 'allow-duplicates' is off - someone won the race. + return done( + `createPolicy("default") threw (${emsg(e)}); another default policy won the race.`, + 'default-policy-lost', + ); + } - // With 'allow-duplicates' the create can succeed yet not be the active default. - if (TT.defaultPolicy && TT.defaultPolicy !== ours) { - return done( - 'Our policy was created but is not the active default (allow-duplicates race lost). ' + - 'Remove "allow-duplicates" from the trusted-types directive.', - 'default-policy-not-active', - ); - } + // With 'allow-duplicates' the create can succeed yet not be the active default. + if (TT.defaultPolicy && TT.defaultPolicy !== ours) { + return done( + 'Our policy was created but is not the active default (allow-duplicates race lost). ' + + 'Remove "allow-duplicates" from the trusted-types directive.', + 'default-policy-not-active', + ); + } - status.defaultPolicyOwned = true; + status.defaultPolicyOwned = true; - if (!status.enforcementActive) { - return done( - 'Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. ' + - 'Deliver require-trusted-types-for (header preferred).', - 'enforcement-inactive', - ); - } - if (!sanitizerReady) { + if (!status.enforcementActive) { + return done( + 'Default policy installed and slot locked, but TT enforcement is NOT active - sinks are not routed. ' + + 'Deliver require-trusted-types-for (header preferred).', + 'enforcement-inactive', + ); + } + if (!sanitizerReady) { + return done( + 'Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW ' + + '(failing closed). Bundle DOMPurify and load it before DOMFortify.', + 'failing-closed', + ); + } return done( - 'Enforcement active and slot locked, but the sanitizer is unavailable - HTML sinks will THROW ' + - '(failing closed). Bundle DOMPurify and load it before DOMFortify.', - 'failing-closed', + `Active: HTML sinks sanitized, script sinks ${allowScript || allowScriptURL ? 'partly allowed by hooks' : 'refused'}.`, ); + } catch (e) { + // Defense in depth: init() must never throw or leave the library bricked with a null status. A + // hostile getter or exotic environment that slips past the guards above fails closed here, with a + // real status object still cached and returned. + return done(`init() hit an unexpected error (${emsg(e)}); failing closed.`, 'failing-closed'); } - return done( - `Active: HTML sinks sanitized, script sinks ${allowScript || allowScriptURL ? 'partly allowed by hooks' : 'refused'}.`, - ); } export function status(): Readonly | null { diff --git a/test/test-suite.mjs b/test/test-suite.mjs index 1930f08..d92bbf8 100644 --- a/test/test-suite.mjs +++ b/test/test-suite.mjs @@ -101,6 +101,8 @@ function cleanup() { delete Object.prototype.ALLOW_SCRIPT; delete Object.prototype.EXCLUDE; delete Object.prototype.URL_CONFIG; + delete Object.prototype.sanitize; + delete Object.prototype.match; } // --- sanitizer resolution ------------------------------------------------------------------------ @@ -134,6 +136,19 @@ QUnit.module('sanitizer resolution', (hooks) => { assert.strictEqual(rules.createHTML(''), '[san]', 'wrapped function used'); }); + QUnit.test('a class-based sanitizer (method on its own prototype) is accepted', async (assert) => { + // The .sanitize lives on the class prototype (below Object.prototype), not as an own key. It must + // still be recognised: the pollution guard only rejects a sanitize reached from Object.prototype. + class S { + sanitize(s) { + return '[class]' + s; + } + } + const { status, rules } = await install({ tt: makeTT(), doc: makeDoc() }, { SANITIZER: new S() }); + assert.true(status.sanitizerReady, 'class instance accepted as a sanitizer'); + assert.strictEqual(rules.createHTML(''), '[class]', 'its prototype sanitize is used'); + }); + QUnit.test('sanitizer returning a non-string fails closed', async (assert) => { const dp = { sanitize: () => ({ not: 'a string' }) }; const { status, rules } = await install({ tt: makeTT(), doc: makeDoc(), DOMPurify: dp }); @@ -166,6 +181,45 @@ QUnit.module('prototype-pollution resistance', (hooks) => { const { rules } = await install({ tt: makeTT(), doc: makeDoc(), DOMPurify: dp }); assert.strictEqual(rules.createScript('alert(1)'), null, 'still refused'); }); + + QUnit.test('polluted Object.prototype.sanitize is not adopted as the sanitizer', async (assert) => { + // Identity "sanitize" on the prototype would pass payloads through untouched if adopted. The + // global sanitizer is a DOM-clobbered truthy non-sanitizer (e.g. window.DOMPurify -> an element), + // which on its own would fail closed; the danger is the prototype method getting mistaken for it. + Object.prototype.sanitize = (s) => s; + const clobbered = { tagName: 'IMG' }; // truthy, no own .sanitize + const { status, rules } = await install({ tt: makeTT(), doc: makeDoc(), DOMPurify: clobbered }); + assert.false(status.sanitizerReady, 'prototype sanitize is not a usable sanitizer'); + assert.strictEqual(rules.createHTML(''), null, 'HTML sink fails closed'); + }); + + QUnit.test('a hostile throwing sanitize getter fails closed, never bricks init', async (assert) => { + const evil = {}; + Object.defineProperty(evil, 'sanitize', { + get() { + throw new Error('boom'); + }, + }); + const { mod, status } = await install({ tt: makeTT(), doc: makeDoc() }, { SANITIZER: evil }); + assert.true(status != null, 'init returned a status object (did not throw or brick)'); + assert.true(mod.status() != null, 'status() is not null after a hostile getter'); + assert.false(status.sanitizerReady, 'sanitizer not ready'); + assert.false(status.protected, 'not protected; HTML sinks fail closed'); + assert.true(status.defaultPolicyOwned, 'default slot still claimed, so nothing else can grab it'); + }); + + QUnit.test('polluted Object.prototype.match cannot apply a rule that lacks its own match', async (assert) => { + Object.prototype.match = '/'; // would match every URL if read off the prototype + const dp = { sanitize: (_s, c) => JSON.stringify(c) }; + const env = { tt: makeTT(), doc: makeDoc(), DOMPurify: dp, location: { href: 'https://app.test/home' } }; + const rule = { SANITIZER_CONFIG: { LOOSENED: true } }; // NO own `match` key + const { rules } = await install(env, { SANITIZER_CONFIG: { strict: true }, URL_CONFIG: [rule] }); + assert.deepEqual( + JSON.parse(rules.createHTML('')), + { strict: true }, + 'base config used; the match-less rule did not apply', + ); + }); }); // --- script sinks --------------------------------------------------------------------------------