Skip to content

wp-kses-svg 0.1.0 — SVG sanitization via wp_kses(), no external libraries

Latest

Choose a tag to compare

@github-actions github-actions released this 04 Jun 06:46
· 1 commit to main since this release

Proof of concept for WordPress Core Trac #24251 (open since 2013).

Demonstrates that SVG uploads can be made safe using only WordPress Core
APIs — no external runtime libraries required.

Security pipeline (8 ordered layers)

  1. XML well-formedness — DOMDocument + LIBXML_NONET | LIBXML_NOENT
  2. Preamble strip — XML declaration, DOCTYPE, HTML comments, whitespace-
    encoded control characters (java script: bypass)
  3. Deny-first threat scanner — blocked tags (script, foreignObject, handler,
    image, feImage), on* event handlers, javascript:/data:/vbscript: schemes,
    SMIL attributeName=on*/style runtime injection, unknown/prefixed tags
  4. Fragment-only href enforcement — reference elements (use, animate, set,
    mpath, textPath, animateTransform, animateMotion); excluded
  5. External url() rejection — filter in/in2 and presentation attributes
    (fill, stroke, filter, clip-path, mask, marker-*)
  6. Inline style sanitization — CSS property allowlist + blocked-value patterns
  7. wp_kses() pass — SVG tag+attribute allowlist with camelCase round-trip;
    quoted-value masking ensures values like fill="viewBox" are never rewritten
  8. Re-validation — sanitised output re-parsed; invalid result -> ''

Architecture

Single-responsibility pipeline stages:
XmlValidator, ThreatScanner, ReferenceGuard, StyleSanitizer, CaseBridge
coordinated by a thin Sanitizer orchestrator. Allowlist memoised; tag-name
lookup is O(1); camelCase round-trip skipped entirely when markup has no
camelCase attribute (~65 us for icon SVGs, ~166 us with camelCase attrs).

Public API

$safe = wp_kses_svg( $raw_svg ); // '' on any failure

Upload pipeline hooks into wp_handle_upload_prefilter, upload_mimes and
wp_check_filetype_and_ext. Capability gate: wp_kses_svg_upload_capability
filter (default: upload_files).

Test suite

143 tests · 4301 assertions · 0 failures · PHP 8.1-8.4
PHPStan clean · PHPCS/WPCS clean
17 SVG fixtures (clean + XSS/SSRF/XXE attack vectors)

CI

GitHub Actions: PHPUnit (8.1/8.2/8.3/8.4), PHPStan, PHPCS/WPCS/PHPCompat,
plugin header consistency, README.md sync check.