PHPwordpressintermediate

Enable SVG Upload Support in WordPress

Safely allow SVG file uploads in WordPress media library

#wordpress#svg#media#upload#security
Share this snippet:

Code

php
1// Enable SVG uploads
2function enable_svg_upload($mimes) {
3 $mimes['svg'] = 'image/svg+xml';
4 $mimes['svgz'] = 'image/svg+xml';
5 return $mimes;
6}
7add_filter('upload_mimes', 'enable_svg_upload');
8
9// Fix SVG display in media library
10function fix_svg_display($response, $attachment, $meta) {
11 if ($response['type'] === 'image' && $response['subtype'] === 'svg+xml') {
12 $response['image'] = array(
13 'src' => $response['url'],
14 );
15 }
16 return $response;
17}
18add_filter('wp_prepare_attachment_for_js', 'fix_svg_display', 10, 3);
19
20// Sanitize SVG files on upload (IMPORTANT for security)
21function sanitize_svg_upload($file) {
22 if ($file['type'] === 'image/svg+xml') {
23 $file_path = $file['tmp_name'];
24 $file_content = file_get_contents($file_path);
25
26 // Remove potentially dangerous tags
27 $dangerous_tags = array(
28 'script',
29 'iframe',
30 'object',
31 'embed',
32 'link'
33 );
34
35 foreach ($dangerous_tags as $tag) {
36 $file_content = preg_replace('/<' . $tag . '[^>]*>.*?<\/' . $tag . '>/is', '', $file_content);
37 $file_content = preg_replace('/<' . $tag . '[^>]*\/>/is', '', $file_content);
38 }
39
40 // Remove on* event handlers
41 $file_content = preg_replace('/\s*on\w+\s*=\s*["\'][^"\']*["\']/i', '', $file_content);
42
43 file_put_contents($file_path, $file_content);
44 }
45
46 return $file;
47}
48add_filter('wp_handle_upload_prefilter', 'sanitize_svg_upload');
49
50// Check file extension and MIME type
51function check_svg_upload($checked, $file, $filename, $mimes) {
52 if (!$checked['type']) {
53 $wp_filetype = wp_check_filetype($filename, $mimes);
54 $ext = $wp_filetype['ext'];
55 $type = $wp_filetype['type'];
56 $proper_filename = $filename;
57
58 if ($type && 0 === strpos($type, 'image/') && $ext !== 'svg') {
59 $ext = $type = false;
60 }
61
62 $checked = compact('ext', 'type', 'proper_filename');
63 }
64
65 return $checked;
66}
67add_filter('wp_check_filetype_and_ext', 'check_svg_upload', 10, 4);

Enable SVG Upload Support in WordPress

WordPress doesn't allow SVG uploads by default due to security concerns. This snippet enables SVG support with proper sanitization to prevent XSS attacks.

// Enable SVG uploads
function enable_svg_upload($mimes) {
    $mimes['svg'] = 'image/svg+xml';
    $mimes['svgz'] = 'image/svg+xml';
    return $mimes;
}
add_filter('upload_mimes', 'enable_svg_upload');

// Fix SVG display in media library
function fix_svg_display($response, $attachment, $meta) {
    if ($response['type'] === 'image' && $response['subtype'] === 'svg+xml') {
        $response['image'] = array(
            'src' => $response['url'],
        );
    }
    return $response;
}
add_filter('wp_prepare_attachment_for_js', 'fix_svg_display', 10, 3);

// Sanitize SVG files on upload (IMPORTANT for security)
function sanitize_svg_upload($file) {
    if ($file['type'] === 'image/svg+xml') {
        $file_path = $file['tmp_name'];
        $file_content = file_get_contents($file_path);

        // Remove potentially dangerous tags
        $dangerous_tags = array(
            'script',
            'iframe',
            'object',
            'embed',
            'link'
        );

        foreach ($dangerous_tags as $tag) {
            $file_content = preg_replace('/<' . $tag . '[^>]*>.*?<\/' . $tag . '>/is', '', $file_content);
            $file_content = preg_replace('/<' . $tag . '[^>]*\/>/is', '', $file_content);
        }

        // Remove on* event handlers
        $file_content = preg_replace('/\s*on\w+\s*=\s*["\'][^"\']*["\']/i', '', $file_content);

        file_put_contents($file_path, $file_content);
    }

    return $file;
}
add_filter('wp_handle_upload_prefilter', 'sanitize_svg_upload');

// Check file extension and MIME type
function check_svg_upload($checked, $file, $filename, $mimes) {
    if (!$checked['type']) {
        $wp_filetype = wp_check_filetype($filename, $mimes);
        $ext = $wp_filetype['ext'];
        $type = $wp_filetype['type'];
        $proper_filename = $filename;

        if ($type && 0 === strpos($type, 'image/') && $ext !== 'svg') {
            $ext = $type = false;
        }

        $checked = compact('ext', 'type', 'proper_filename');
    }

    return $checked;
}
add_filter('wp_check_filetype_and_ext', 'check_svg_upload', 10, 4);

Display SVG Dimensions

// Add SVG dimensions
function add_svg_dimensions($dimensions, $image_src, $image_meta, $attachment_id) {
    if (get_post_mime_type($attachment_id) === 'image/svg+xml') {
        $svg_path = get_attached_file($attachment_id);
        $svg_content = file_get_contents($svg_path);

        preg_match('/width=["\'](\d+)["\']/', $svg_content, $width_match);
        preg_match('/height=["\'](\d+)["\']/', $svg_content, $height_match);

        if ($width_match && $height_match) {
            $dimensions = array(
                intval($width_match[1]),
                intval($height_match[1])
            );
        }
    }

    return $dimensions;
}
add_filter('wp_get_attachment_image_src', 'add_svg_dimensions', 10, 4);

Security Considerations

  • Sanitization Required: Always sanitize SVG files to prevent XSS attacks
  • Trusted Users Only: Only allow SVG uploads for admin users
  • Regular Updates: Keep WordPress and plugins updated
  • Backup First: Test on staging before production

Restrict SVG Upload to Admins Only

// Only allow admins to upload SVG
function restrict_svg_to_admins($mimes) {
    if (!current_user_can('administrator')) {
        unset($mimes['svg']);
        unset($mimes['svgz']);
    }
    return $mimes;
}
add_filter('upload_mimes', 'restrict_svg_to_admins', 999);

Related Snippets