diff --git a/README.md b/README.md
index db34c8a..1f784da 100644
--- a/README.md
+++ b/README.md
@@ -83,7 +83,7 @@ could reach. Pin both with SRI so a bad CDN day fails closed instead of open:
>
```
diff --git a/dist/fortify.cjs.js b/dist/fortify.cjs.js
index 151edb8..93264b0 100644
--- a/dist/fortify.cjs.js
+++ b/dist/fortify.cjs.js
@@ -1,4 +1,4 @@
-/*! DOMFortify 1.0.0 | (c) Cure53 and contributors | (MPL-2.0 OR Apache-2.0) */
+/*! DOMFortify 1.0.1 | (c) Cure53 and contributors | (MPL-2.0 OR Apache-2.0) */
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
@@ -82,7 +82,7 @@ function urlMatches(pattern, url) {
* - Fails closed: no sanitizer means sinks throw, never leak.
* - Only covers Trusted Types sinks; inline handlers / style / URL props stay open.
*/
-const VERSION = '1.0.0';
+const VERSION = '1.0.1';
// Natives captured up front, so later prototype pollution or clobbering can't swap them out.
const root = typeof globalThis !== 'undefined' ? globalThis : window;
const doc = typeof document !== 'undefined' ? document : undefined;
diff --git a/dist/fortify.es.mjs b/dist/fortify.es.mjs
index be24e7f..9cf892e 100644
--- a/dist/fortify.es.mjs
+++ b/dist/fortify.es.mjs
@@ -1,4 +1,4 @@
-/*! DOMFortify 1.0.0 | (c) Cure53 and contributors | (MPL-2.0 OR Apache-2.0) */
+/*! DOMFortify 1.0.1 | (c) Cure53 and contributors | (MPL-2.0 OR Apache-2.0) */
// Cached up front so later prototype pollution or clobbering can't swap hasOwnProperty out.
const hasOwn = Object.prototype.hasOwnProperty;
/** True only for an own (non-inherited) property, so a polluted prototype is never consulted. */
@@ -78,7 +78,7 @@ function urlMatches(pattern, url) {
* - Fails closed: no sanitizer means sinks throw, never leak.
* - Only covers Trusted Types sinks; inline handlers / style / URL props stay open.
*/
-const VERSION = '1.0.0';
+const VERSION = '1.0.1';
// Natives captured up front, so later prototype pollution or clobbering can't swap them out.
const root = typeof globalThis !== 'undefined' ? globalThis : window;
const doc = typeof document !== 'undefined' ? document : undefined;
diff --git a/dist/fortify.js b/dist/fortify.js
index 9c0522b..b46420f 100644
--- a/dist/fortify.js
+++ b/dist/fortify.js
@@ -1,4 +1,4 @@
-/*! DOMFortify 1.0.0 | (c) Cure53 and contributors | (MPL-2.0 OR Apache-2.0) */
+/*! DOMFortify 1.0.1 | (c) Cure53 and contributors | (MPL-2.0 OR Apache-2.0) */
(function () {
'use strict';
@@ -81,7 +81,7 @@
* - Fails closed: no sanitizer means sinks throw, never leak.
* - Only covers Trusted Types sinks; inline handlers / style / URL props stay open.
*/
- const VERSION = '1.0.0';
+ const VERSION = '1.0.1';
// Natives captured up front, so later prototype pollution or clobbering can't swap them out.
const root = typeof globalThis !== 'undefined' ? globalThis : window;
const doc = typeof document !== 'undefined' ? document : undefined;
diff --git a/dist/fortify.min.js b/dist/fortify.min.js
index fd10706..4e13032 100644
--- a/dist/fortify.min.js
+++ b/dist/fortify.min.js
@@ -1,3 +1,3 @@
-/*! DOMFortify 1.0.0 | (c) Cure53 and contributors | (MPL-2.0 OR Apache-2.0) */
-!function(){"use strict";const t=Object.prototype.hasOwnProperty;function e(e,n){return null!=e&&t.call(e,n)}function n(t,n){return e(t,n)?t[n]:void 0}function r(t){return String(t).slice(0,80)}function i(t){try{return String(t?.message)}catch{return"unknown error"}}function o(t,e){if(null==t)return!1;const n=Array.isArray(t)?t:[t];for(let t=0;t{if(!n)return r("sanitizer-unavailable",{sink:"createHTML"}),null;if(o)return c;try{return o=!0,t.sanitize(c,e)}catch(t){return r("sanitize-threw",{error:i(t)}),null}finally{o=!1}}}function p(t,e,n){return o=>{if(e){let r;try{r=e(o)}catch(e){return n("script-hook-threw",{sink:t,error:i(e)}),null}if("string"==typeof r)return n("script-sink-allowed",{sink:t}),r}return n("script-sink-refused",{sink:t,sample:r(o)}),null}}const h=Object.freeze({init:function(r={}){if(s)return f;s=!0;const h=n(r,"ON_VIOLATION"),O="function"==typeof h?(t,e)=>{try{h(t,e)}catch{}}:()=>{},v={version:"1.0.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&&O(e,f),f);try{const s=a&&void 0!==a.href?String(a.href):"";if(o(n(r,"EXCLUDE"),s))return v.excluded=!0,m("URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.","excluded-by-url");const f=n(r,"INCLUDE");if(null!=f&&!o(f,s))return v.excluded=!0,m("URL is outside INCLUDE scope; DOMFortify is intentionally inactive on this page.","outside-include-scope");if(!l||"function"!=typeof l.createPolicy)return m("Trusted Types not supported; library is inert. Sinks are NOT routed.","tt-unsupported");const h=function(t,e){const r=n(t,"URL_CONFIG");if(!Array.isArray(r))return null;for(let t=0;th&&e(h,t)?h[t]:n(r,t);if(!0===n(r,"INJECT_META")){const t=(T=n(r,"META_DIRECTIVE"),w="function"==typeof g("SANITIZER"),"string"==typeof T&&T?T:`require-trusted-types-for 'script'; trusted-types ${w?"default":"default dompurify"};`);v.metaInjected=function(t){if(!u)return!1;const e=u,n='\r\n]/g,"")+'">';if("loading"===e.readyState&&"function"==typeof e.write)try{return e.write(n),!0}catch{}try{const n=e.createElement("meta");n.setAttribute("http-equiv","Content-Security-Policy"),n.setAttribute("content",t),(e.head||e.documentElement).appendChild(n)}catch{}return!1}(t),O("meta-injection-attempted",{directive:t,written:v.metaInjected})}v.enforcementActive=function(){try{return u.createElement("div").innerHTML="x",!1}catch{return!0}}();let b=g("SANITIZER");void 0===b&&(b=c.DOMPurify);const L=d(b),A=g("SANITIZER_CONFIG"),I=A&&"object"==typeof A?function(e){const n={};for(const r in e)t.call(e,r)&&"__proto__"!==r&&"constructor"!==r&&"prototype"!==r&&(n[r]=e[r]);return n}(A):void 0,E=g("ALLOW_SCRIPT"),R=g("ALLOW_SCRIPT_URL"),k="function"==typeof E?E:null,P="function"==typeof R?R:null;let S=!1;if(L){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)}}}(L,I);S=t.ready,t.ready||O("sanitizer-smoketest-failed",{error:t.error})}v.sanitizerReady=S;const z={createHTML:y(L,I,S,O),createScript:p("createScript",k,O),createScriptURL:p("createScriptURL",P,O)};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 D;try{D=l.createPolicy("default",z)}catch(t){return m(`createPolicy("default") threw (${i(t)}); another default policy won the race.`,"default-policy-lost")}return l.defaultPolicy&&l.defaultPolicy!==D?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?S?m(`Active: HTML sinks sanitized, script sinks ${k||P?"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"))}catch(t){return m(`init() hit an unexpected error (${i(t)}); failing closed.`,"failing-closed")}var T,w},status:function(){return f}});"undefined"!=typeof window&&(window.DOMFortify=h,h.init(window.DOMFortifyConfig||{}))}();
+/*! DOMFortify 1.0.1 | (c) Cure53 and contributors | (MPL-2.0 OR Apache-2.0) */
+!function(){"use strict";const t=Object.prototype.hasOwnProperty;function e(e,n){return null!=e&&t.call(e,n)}function n(t,n){return e(t,n)?t[n]:void 0}function r(t){return String(t).slice(0,80)}function i(t){try{return String(t?.message)}catch{return"unknown error"}}function o(t,e){if(null==t)return!1;const n=Array.isArray(t)?t:[t];for(let t=0;t{if(!n)return r("sanitizer-unavailable",{sink:"createHTML"}),null;if(o)return c;try{return o=!0,t.sanitize(c,e)}catch(t){return r("sanitize-threw",{error:i(t)}),null}finally{o=!1}}}function p(t,e,n){return o=>{if(e){let r;try{r=e(o)}catch(e){return n("script-hook-threw",{sink:t,error:i(e)}),null}if("string"==typeof r)return n("script-sink-allowed",{sink:t}),r}return n("script-sink-refused",{sink:t,sample:r(o)}),null}}const h=Object.freeze({init:function(r={}){if(s)return f;s=!0;const h=n(r,"ON_VIOLATION"),O="function"==typeof h?(t,e)=>{try{h(t,e)}catch{}}:()=>{},v={version:"1.0.1",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&&O(e,f),f);try{const s=a&&void 0!==a.href?String(a.href):"";if(o(n(r,"EXCLUDE"),s))return v.excluded=!0,m("URL matched EXCLUDE; DOMFortify is intentionally inactive on this page.","excluded-by-url");const f=n(r,"INCLUDE");if(null!=f&&!o(f,s))return v.excluded=!0,m("URL is outside INCLUDE scope; DOMFortify is intentionally inactive on this page.","outside-include-scope");if(!l||"function"!=typeof l.createPolicy)return m("Trusted Types not supported; library is inert. Sinks are NOT routed.","tt-unsupported");const h=function(t,e){const r=n(t,"URL_CONFIG");if(!Array.isArray(r))return null;for(let t=0;th&&e(h,t)?h[t]:n(r,t);if(!0===n(r,"INJECT_META")){const t=(T=n(r,"META_DIRECTIVE"),w="function"==typeof g("SANITIZER"),"string"==typeof T&&T?T:`require-trusted-types-for 'script'; trusted-types ${w?"default":"default dompurify"};`);v.metaInjected=function(t){if(!u)return!1;const e=u,n='\r\n]/g,"")+'">';if("loading"===e.readyState&&"function"==typeof e.write)try{return e.write(n),!0}catch{}try{const n=e.createElement("meta");n.setAttribute("http-equiv","Content-Security-Policy"),n.setAttribute("content",t),(e.head||e.documentElement).appendChild(n)}catch{}return!1}(t),O("meta-injection-attempted",{directive:t,written:v.metaInjected})}v.enforcementActive=function(){try{return u.createElement("div").innerHTML="x",!1}catch{return!0}}();let b=g("SANITIZER");void 0===b&&(b=c.DOMPurify);const L=d(b),A=g("SANITIZER_CONFIG"),I=A&&"object"==typeof A?function(e){const n={};for(const r in e)t.call(e,r)&&"__proto__"!==r&&"constructor"!==r&&"prototype"!==r&&(n[r]=e[r]);return n}(A):void 0,E=g("ALLOW_SCRIPT"),R=g("ALLOW_SCRIPT_URL"),k="function"==typeof E?E:null,P="function"==typeof R?R:null;let S=!1;if(L){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)}}}(L,I);S=t.ready,t.ready||O("sanitizer-smoketest-failed",{error:t.error})}v.sanitizerReady=S;const z={createHTML:y(L,I,S,O),createScript:p("createScript",k,O),createScriptURL:p("createScriptURL",P,O)};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 D;try{D=l.createPolicy("default",z)}catch(t){return m(`createPolicy("default") threw (${i(t)}); another default policy won the race.`,"default-policy-lost")}return l.defaultPolicy&&l.defaultPolicy!==D?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?S?m(`Active: HTML sinks sanitized, script sinks ${k||P?"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"))}catch(t){return m(`init() hit an unexpected error (${i(t)}); failing closed.`,"failing-closed")}var T,w},status:function(){return f}});"undefined"!=typeof window&&(window.DOMFortify=h,h.init(window.DOMFortifyConfig||{}))}();
//# sourceMappingURL=fortify.min.js.map
diff --git a/package-lock.json b/package-lock.json
index e53408d..fcc6cfb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "domfortify",
- "version": "1.0.0",
+ "version": "1.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "domfortify",
- "version": "1.0.0",
+ "version": "1.0.1",
"license": "(MPL-2.0 OR Apache-2.0)",
"devDependencies": {
"@playwright/test": "^1.49.0",
diff --git a/package.json b/package.json
index 223f608..e87506a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "domfortify",
- "version": "1.0.0",
+ "version": "1.0.1",
"description": "Retrofit Trusted Types onto a legacy page: claim the realm's default policy so old DOM-XSS sinks get sanitized without touching the code.",
"license": "(MPL-2.0 OR Apache-2.0)",
"homepage": "https://github.com/cure53/DOMFortify",