Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ Content-Security-Policy: require-trusted-types-for 'script'; trusted-types defau
/>
```

...or, when you can place neither, let DOMFortify inject that `<meta>` for you with one config flag:

```js
window.DOMFortifyConfig = { INJECT_META: true };
```

This is best-effort and only takes when DOMFortify runs during the initial parse (inline, first thing
in `<head>`); a header or hand-placed `<meta>` is still sturdier. Confirm it took with
`status().enforcementActive`. Details in [Turning enforcement on](#turning-enforcement-on-advanced).

Second, load the sanitizer and then DOMFortify **first thing in `<head>`**, before anything an attacker
could reach. Pin both with SRI so a bad CDN day fails closed instead of open:

Expand Down
20 changes: 17 additions & 3 deletions dist/fortify.cjs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/fortify.cjs.js.map

Large diffs are not rendered by default.

20 changes: 17 additions & 3 deletions dist/fortify.es.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,20 @@ function init(options = {}) {
if (installed)
return cachedStatus;
installed = true;
// The violation reporter is observability, never control flow. Wrap it so a throwing ON_VIOLATION
// can neither abort init() (which would leave us installed with a null status) nor turn a
// fail-closed sink - one that should quietly return null - into a thrown exception.
const onv = cfg(options, 'ON_VIOLATION');
const report = typeof onv === 'function' ? onv : () => { };
const report = typeof onv === 'function'
? (code, detail) => {
try {
onv(code, detail);
}
catch {
/* a misbehaving reporter must never break the policy */
}
}
: () => { };
const status = {
version: VERSION,
ttSupported: !!TT,
Expand All @@ -239,9 +251,11 @@ function init(options = {}) {
const done = (reason, code) => {
status.protected = status.defaultPolicyOwned && status.enforcementActive && status.sanitizerReady;
status.reason = reason;
if (code)
report(code, status);
// Freeze the snapshot first, then report it: the reporter sees exactly the authoritative status
// that gets cached and returned, and has no window to mutate the cached copy.
cachedStatus = Object.freeze({ ...status });
if (code)
report(code, cachedStatus);
return cachedStatus;
};
const url = loc && typeof loc.href !== 'undefined' ? String(loc.href) : '';
Expand Down
2 changes: 1 addition & 1 deletion dist/fortify.es.mjs.map

Large diffs are not rendered by default.

20 changes: 17 additions & 3 deletions dist/fortify.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/fortify.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/fortify.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading