Skip to content

feat(security): add Trusted Types support#4816

Open
alexemorris wants to merge 8 commits into
slab:mainfrom
alexemorris:feat/trusted-types-support
Open

feat(security): add Trusted Types support#4816
alexemorris wants to merge 8 commits into
slab:mainfrom
alexemorris:feat/trusted-types-support

Conversation

@alexemorris

@alexemorris alexemorris commented Jul 1, 2026

Copy link
Copy Markdown

This PR adds Trusted Types support to Quill to make it easier to run in strict security environments.

Changes:

  • Added a centralized Trusted Types policy helper.
  • Fixed innerHTML and parseFromString violations.
  • Switched to safevalues for sanitizing links and images instead of custom stuff.
  • Used htmlSafeByReview for the built-in SVG icons so they don't get stripped but stay secure.
  • Cleaned up some innerHTML = '' usages.

Caveats:

  • The Video format (iframe.src) is not updated to use safevalues as it requires TrustedResourceUrl which is difficult to apply generically without knowing the specific domains beforehand. It continues to use standard setAttribute with existing sanitization.

Passes existing tests.

Alex Morris added 8 commits July 1, 2026 05:41
This change makes Quill compatible with strict Trusted Types environments by optionally using a Trusted Types Policy when available.
Replacing innerHTML = '' with textContent = '' is faster and avoids unnecessary HTML parsing/conformance triggers.
…TML usages

Introduced a shared html utility for Trusted Types and replaced verbose innerHTML assignments in UI components with setTrustedInnerHtml.
Replaced direct setAttribute('href', ...) with setAnchorHref from safevalues/dom to improve security compliance.
Replaced direct setAttribute('src', ...) with setElementAttribute from safevalues/dom to improve security compliance.
Replaced custom Trusted Types helpers with standard safevalues sanitizers for IconPicker, ColorPicker, Picker, and BaseTheme.
@alexemorris
alexemorris force-pushed the feat/trusted-types-support branch from f44a3a1 to 754fd7f Compare July 1, 2026 09:34
@0xLeif

0xLeif commented Jul 23, 2026

Copy link
Copy Markdown

Review (via AI-assisted code review): REQUEST CHANGES

The direction (Trusted Types compatibility, dropping custom URL munging in favor of safevalues) is good, but there are blocking issues:

  1. New runtime dependency without a lockfile update. safevalues ^1.2.0 is added to packages/quill/package.json dependencies, but no package-lock.json change is included (the PR touches 12 files, none of them the root lockfile). npm ci in CI and for contributors will fail with a lock-out-of-sync error. Please regenerate and commit the lockfile.

  2. The central Trusted Types policy is an unsanitized passthrough. core/utils/html.ts creates a policy named quill with createHTML: (s) => s. This provides zero protection: any application that enables Trusted Types and allowlists the quill policy name (a natural thing to do once this ships) re-opens every sink Quill feeds through it with no review. It also silently no-ops when policy creation throws (e.g., CSP trusted-types directive with a restricted policy-name allowlist), which is fine, but the feature as implemented is compliance theater rather than a security improvement. Either sanitize inside the policy, restrict its use to inputs that are actually trusted, or document clearly that it exists only to satisfy require-trusted-types-for and must not be allowlisted blindly.

  3. Sink coverage is partial. parseFromString is wrapped, but DOMParser.parseFromString is not in Chromium's default Trusted Types sink set, so the main wrapper addresses a non-violation, while real innerHTML sinks outside the picker/theme path (e.g. tooltips, normalizeExternalHTML) are untouched. The PR claims to fix "innerHTML and parseFromString violations" but only covers the icon/picker subset.

  4. Tests don't test the feature. The added image.spec.ts/video.spec.ts only re-assert existing sanitize behavior (javascript: → //:0/about:blank) — nothing exercises Trusted Types enforcement, the policy fallback, or that the safevalues setters behave identically to setAttribute under a require-trusted-types-for 'script' document. At minimum add a test with a TT-enforcing stub.

Also minor: setElementAttribute(node, 'src', ...) from safevalues/dom rejects security-sensitive attribute/element combinations for plain strings — please verify img src with a string value doesn't throw under safevalues' checks. And the diff adds stray blank lines in several files.

Branch is based on current main; the video iframe caveat is acknowledged and reasonable. No CI has run on this fork head yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants