CodePros SVG Secure Support
WordPress does not support SVG uploads natively — and naive SVG plugins are a well-known attack surface. SVG files are XML documents that can carry XSS payloads, XXE attacks, external resource injection, and embedded HTML. CodePros SVG Secure Support adds safe, production-ready SVG uploads through a layered defense pipeline.
Security Pipeline
Every uploaded SVG passes through five sequential checks before it is accepted:
- Extension check — Blocks double-extension filenames (e.g.
payload.php.svg) and enforces.svgonly. - MIME check — Verifies actual file bytes return
image/svg+xmlviafinfo; confirms<svgor<?xmlis present in the header bytes. - Size check — Rejects files exceeding the configured maximum (default 1 MB).
- Node-count check — Parses the XML and counts DOM nodes; rejects files above the threshold (default 5,000 nodes) to prevent node-flood DoS attacks.
- Dimension check — Reads the root
<svg>width/height/viewBox; rejects unreasonably large declared dimensions (default 10,000 px).
After validation, the file is sanitized:
- DOM sanitization via the battle-tested enshrined/svg-sanitize library with custom tag and attribute whitelists.
- Remote reference stripping — all external URLs are removed.
- Final string-level regex scan for
javascript:,<script, inline event handlers (on*=), and CSSexpression()— any match causes the upload to be rejected entirely.
Security Headers
When SVG attachment pages are served, the plugin adds:
Content-Security-Policy(configurable, secure default provided)X-Content-Type-Options: nosniffX-Frame-Options: SAMEORIGIN
Server-Level Hardening (Optional but Recommended)
The plugin’s PHP layer covers every SVG upload that passes through WordPress. But if someone accesses an uploaded file directly — e.g. by visiting https://example.com/wp-content/uploads/2024/01/logo.svg — WordPress is bypassed entirely, so the PHP security headers are never sent.
The plugin ships two ready-to-use server configuration snippets to close that gap:
uploads-htaccess.txt— for Apache / LiteSpeed serversuploads-nginx.conf— for Nginx servers
Each snippet does three things:
- Blocks server-side script execution in
wp-content/uploads/— if an attacker somehow uploads a.phpfile and tries to access it directly, the server returns 403 instead of executing it. - Enforces the correct SVG MIME type (
image/svg+xml) — some server setups serve SVGs astext/plain, which prevents browsers from honouring Content Security Policy rules scoped to that MIME type. - Adds security headers on direct SVG requests — the same
X-Content-Type-Options,X-Frame-Options, andContent-Security-Policyheaders that the PHP layer adds on WordPress attachment pages, so direct file links are equally protected.
Applying these snippets is the difference between WordPress-mediated access being protected and all access (direct URL, CDN pull, hotlink) being protected.
Admin UI
A tabbed settings page under Settings → SVG Secure Support provides:
- Settings tab — Configure allowed upload roles, file size/node/dimension limits, sanitization options, CSP header value, and logging preferences.
- Security Logs tab — Paginated, filterable log viewer showing every security event (blocked upload, removed tag/attribute, suspicious payload). Includes a log purge action.
Key Features
- Role-based upload access — select one or more WordPress roles (default: Administrator) whose members may upload SVG files
- Automatic upload-time sanitization — clean SVG replaces the original tmp file before WordPress moves it
- Security event logging to the WordPress debug log and a dedicated database table
- Configurable log retention with one-click purge
- Bundled
.htaccessand Nginx config snippets for the uploads directory
