Skip to content

proof-of-concept: sanitise via bundled svg-hush, remove bespoke sanitizer#1

Draft
davidtaylorhq wants to merge 1 commit into
mainfrom
svg-hush-sanitizer
Draft

proof-of-concept: sanitise via bundled svg-hush, remove bespoke sanitizer#1
davidtaylorhq wants to merge 1 commit into
mainfrom
svg-hush-sanitizer

Conversation

@davidtaylorhq

Copy link
Copy Markdown
Member

(AI-authored experiment. Unsuitable for merge)


Replace the in-house REXML/SvgCss SVG sanitizer with Cloudflare's memory-safe, fuzzed svg-hush, bundled as a prebuilt per-platform binary and run through the existing argv-only + Landlock path (no FFI). This deletes ~1.5k lines of bespoke parsing/CSS-allowlist code and the bug class that came with it: the prior delete_attribute(local_name) path let a namespace-prefixed onload survive on a real <svg> element, an executing same-origin XSS in :standalone output.

sanitize_svg!(path, max_pixels:) now produces document-safe output only (the id_namespace: inline-into-DOM layer is removed). SvgMetadata still enforces the byte-size, encoding, and pixel pre-checks before the binary runs, so the LimitError/InvalidImageError hierarchy is unchanged. The operation no longer routes through the sandbox worker; svg-hush is its own sandboxed subprocess, and Sandbox.capture_command! now grants Landlock execute on the command's own directory so a gem-bundled binary outside the system bin dirs can run.

Binaries are produced by script/build-svg-hush.sh from a pinned svg-hush version and vendored under vendor/svg-hush/; an unbundled platform raises rather than compiling at install.

Replace the in-house REXML/`SvgCss` SVG sanitizer with Cloudflare's memory-safe, fuzzed `svg-hush`, bundled as a prebuilt per-platform binary and run through the existing argv-only + Landlock path (no FFI). This deletes ~1.5k lines of bespoke parsing/CSS-allowlist code and the bug class that came with it: the prior `delete_attribute(local_name)` path let a namespace-prefixed `onload` survive on a real `<svg>` element, an executing same-origin XSS in `:standalone` output.

`sanitize_svg!(path, max_pixels:)` now produces document-safe output only (the `id_namespace:` inline-into-DOM layer is removed). `SvgMetadata` still enforces the byte-size, encoding, and pixel pre-checks before the binary runs, so the `LimitError`/`InvalidImageError` hierarchy is unchanged. The operation no longer routes through the sandbox worker; `svg-hush` is its own sandboxed subprocess, and `Sandbox.capture_command!` now grants Landlock execute on the command's own directory so a gem-bundled binary outside the system bin dirs can run.

Binaries are produced by `script/build-svg-hush.sh` from a pinned `svg-hush` version and vendored under `vendor/svg-hush/`; an unbundled platform raises rather than compiling at install.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant