Escaping and sanitizing SVGs in metabox textarea

I want to include inline SVGs in a metabox textarea.

That's easy. What's killing me is how do I sanitize the textarea before saving the postmeta, and how do I escape it?

Halp?

Thanks!

Topic svg sanitization escaping Wordpress

Category Web


Safe SVG (mentioned by @Marc) is by far the best WP plugin I've seen.

It's important to note, though, that it's likely there are ways to bypass it. SVGs are insecure by design; we all think of them as images, but in reality they're mini XML applications.

DOMPurify is the only reliably secure solution that I'm aware of. That's because it runs in JavaScript, so it can analyze objects after they've been parsed by the engine. It's impossible for PHP to do that. You can read more about it in #24251-core.

For most sites, though, Safe SVG is probably a good compromise. For a mission-critical/enterprise/ecommerce site, though, I'd recommend running it through DOMPurify (although it wont be easy).

  1. Hook into WP's upload process, probably via the pre_move_uploaded_file filter provided by _wp_handle_upload().
  2. Get the value of the uploaded SVG from $file as a string, and make an HTTPS request to a Node.js API.
  3. Setup the Node app to accept the string, run it through DOMPurify, and return the result.
  4. The PHP plugin can then save the sanitized result.

To be practical, though, it's probably better to just avoid SVGs in situations like this, and use an actual image format instead.


Here is a PHP library that was created for sanitizing SVG files that may be worth looking into. https://github.com/darylldoyle/svg-sanitizer

Here is an example of how this could be used:

// Now do what you want with your clean SVG/XML data

function your_save_meta( $post_id, $post, $update ) {

    // - Update the post's metadata.

    if ( isset( $_POST['svg_meta'] ) ) {

        // Load the sanitizer. (This path will need to be updated)
        use enshrined\svgSanitize\Sanitizer;

        // Create a new sanitizer instance
        $sanitizer = new Sanitizer();

        // Pass your meta data to the sanitizer and get it back clean
        $cleanSVG = $sanitizer->sanitize($_POST['svg_meta']);

        // Update your post meta
        update_post_meta( $post_id, 'svg_meta_name', $cleanSVG );

    }

}
add_action( 'save_post', 'your_save_meta', 10, 3 );

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.