WordPress File Upload Plugin < 4.23.3 - Stored XSS

Exploit Author: Faiyaz Ahmad Analysis Author: www.bubbleslearn.ir Category: WebApps Language: PHP Published Date: 2024-03-18
Exploit Title: WordPress File Upload < 4.23.3 Stored XSS (CVE 2023-4811)
Date: 18 December 2023
Exploit Author: Faiyaz Ahmad
Vendor Homepage: https://wordpress.com/
Version: 4.23.3
CVE : CVE 2023-4811

Proof Of Concept:

1. Login to the wordpress account

2. Add the following shortcode to a post in "File Upload Plugin":

[wordpress_file_upload redirect="true" redirectlink="*javascript:alert(1)*"]

3. Upload any file on the resulting post.
4. After the upload completes, you will see the XSS alert in the browser.


WordPress File Upload Plugin < 4.23.3 — Stored Cross‑Site Scripting (CVE‑2023‑4811)

This article explains the stored cross‑site scripting (XSS) vulnerability tracked as CVE‑2023‑4811 affecting versions of the WordPress File Upload plugin prior to 4.23.3. It covers what the issue is, how it works at a high level, risk and impact, detection and mitigation strategies, safe coding fixes, and recommended operational practices for site owners and developers.

Executive summary

ItemDetails
VulnerabilityStored XSS in File Upload plugin (shortcode attribute is not properly validated/escaped)
CVECVE‑2023‑4811
Affected versionsFile Upload plugin versions prior to 4.23.3
SeverityHigh — stored XSS can run in context of logged users and potentially administrators
MitigationUpdate plugin to 4.23.3 or later; apply input validation, escape on output, use WordPress URL helpers

What is the vulnerability (high level)

Stored XSS occurs when attacker-supplied input is stored by the application and later rendered to a user without proper sanitization or escaping, allowing arbitrary JavaScript to execute in the victim’s browser. In this case, an attribute used by the plugin’s shortcode that controls a redirect destination was not strictly validated and escaped. The unsanitized value could be stored in post content and later rendered in a context where the browser executed script code supplied by an attacker.

Risk and impact

  • Stored XSS can lead to session theft, account takeover, persistent defacements, malicious redirects, or execution of actions in the context of an authenticated user.
  • If an administrator or other privileged user views an affected page, the impact is higher (site takeover, plugin/theme file edits, user creation, etc.).
  • Sites using the plugin that allow untrusted contributors to create or edit posts are especially at risk.

How the issue typically manifests (conceptual)

Shortcode attributes (or other user-supplied fields) that are stored in the database later get injected into HTML output. If the value includes a dangerous URI scheme (for example, a javascript: URL) or embedded markup and the plugin outputs it without sufficient validation/escaping, the browser may execute that code when the page is rendered or when a redirect is triggered.

Detection and hunting

  • Search post content for occurrences of the plugin shortcode that include suspicious redirect targets (e.g., values containing non‑http(s) schemes such as "javascript:").
  • Scan database posts for the specific shortcode attribute name used by the plugin and look for values that contain script, on* attributes, or ":" schemes that are not http(s).
  • Review web server and application logs for requests containing the shortcode or anomalous redirects originating from pages served by the plugin.
  • Use a security scanner or WAF rules that detect JavaScript scheme usage or inline event handlers inside user-supplied URL fields.

Example search patterns you can use safely as part of an incident hunt:

  • Search for posts with the shortcode name and a non‑http/https scheme in the attribute value (e.g., looking for "redirectlink=" followed by a colon other than http/https).
  • Search for "javascript:" or "data:text/html" inside post_content (note: these strings may appear legitimately but are indicators when present in shortcode attributes).

Immediate mitigations for site owners

  • Update the File Upload plugin to version 4.23.3 or later as soon as possible — this is the primary fix.
  • If you cannot update immediately, restrict who can edit posts and use the plugin (remove untrusted contributor privileges), and disable the plugin temporarily if feasible.
  • Sanitize or remove suspicious shortcode instances from stored posts — look for redirect attributes containing non‑http(s) schemes or script content and remove or correct them.
  • Harden content security policies (CSP) and consider enabling a WAF to block attempts to inject dangerous payloads.

Developer guidance and secure fixes

Fixing this class of issue requires both input validation and correct escaping on output. For URLs and redirect targets in WordPress, use the built‑in URL validation and escaping helpers rather than performing ad‑hoc string checks.

Key WordPress functions to use:

  • wp_validate_redirect($location, $default) — validates a redirect URL and prevents unsafe schemes (returns the default if invalid).
  • wp_safe_redirect($location) — performs a safe redirect to permitted hosts/schemes.
  • esc_url_raw(), esc_url() — for sanitizing/escaping URLs (esc_url for output, esc_url_raw for storage/processing).
  • esc_attr(), esc_html() — for escaping before injecting into attributes or HTML.

Safe shortcode handling (example)

function fwu_safe_shortcode( $atts ) {
    $atts = shortcode_atts(
        array(
            'redirect'     => 'false',
            'redirectlink' => '',
        ),
        $atts,
        'wordpress_file_upload'
    );

    // Normalize input
    $raw = isset( $atts['redirectlink'] ) ? trim( wp_unslash( $atts['redirectlink'] ) ) : '';

    // Validate and normalize redirect URL — uses WordPress helper to avoid unsafe schemes.
    $validated = wp_validate_redirect( $raw, '' ); // returns '' (default) if invalid

    // When rendering, always escape output.
    $safe_redirect_attr = esc_attr( $validated );

    // Build safe HTML output (example snippet)
    $output  = '
'; $output .= esc_html__( 'Upload your file', 'fwu' ); $output .= '
'; return $output; }

Explanation:

  • The code normalizes shortcode attributes with shortcode_atts and trims the redirectlink value.
  • wp_validate_redirect enforces only safe schemes and returns a safe default if the input is not an allowed redirect.
  • When the value is output into HTML, esc_attr is used to prevent injection into attributes. esc_html is used for visible text.

Safe redirect handling when performing an actual redirect (example)

// Example: perform a redirect using user-provided URL safely
$raw = isset( $_POST['redirectlink'] ) ? trim( wp_unslash( $_POST['redirectlink'] ) ) : '';
$redirect = wp_validate_redirect( $raw, home_url() ); // default to home if invalid
if ( $redirect ) {
    wp_safe_redirect( $redirect );
    exit;
}

Explanation:

  • wp_validate_redirect validates scheme and structure; if the input is invalid it returns the provided default (home_url()), preventing javascript: and similar schemes.
  • wp_safe_redirect ensures the destination is safe for redirection, then execution exits immediately after redirect to avoid further output.

Post‑remediation checks

  • After patching the plugin, search the database for any stored shortcode instances that contain previously unsafe values and remove or correct them.
  • Review recent post edits and plugin usage logs to identify potential abuse prior to patching.
  • Run a site scan for XSS indicators and validate that CSP and security headers are in place.

Responsible disclosure and timeline

Vendors and plugin authors typically publish security advisories and release patched versions for known CVEs. If you discover a vulnerability, follow coordinated disclosure practices: report privately to the plugin author or vendor, allow reasonable time for a fix, and only publish technical details after a patch is available to protect users.

References and further reading

  • WordPress developer resources: functions like wp_validate_redirect(), wp_safe_redirect(), esc_url(), esc_attr()
  • OWASP XSS Prevention Cheat Sheet — general guidance on input validation and output encoding
  • Official plugin changelog / security advisory (check the plugin page for 4.23.3 release notes)

Conclusion

CVE‑2023‑4811 illustrates how user-supplied data in shortcode attributes or other storage locations can lead to persistent XSS when not validated and escaped correctly. Applying the vendor patch (update to File Upload 4.23.3+), hardening permissions, and using WordPress built-in sanitization/validation functions will mitigate this risk. Developers should apply defense‑in‑depth: validate input, escape output, and adopt secure redirect helpers for any user‑supplied URLs.