Share
## https://sploitus.com/exploit?id=23F51EEB-70AA-5EEB-B2F4-47786BC81C6E
# CVE-2025-14855: SureForms WordPress Plugin Stored XSS Proof of Concept
- **Target:** WordPress Plugin "SureForms"
- **Vulnerability Type:** Stored Cross-Site Scripting (XSS)
- **CVE:** CVE-2025-14855
- **Authentication:** Unauthenticated (Guest/Public)
- **Impact:** Remote Code Execution (RCE) via Admin Session Hijacking
- **Discovered by:** https://nguyentiendung1006.wixsite.com/tiendung

## 1. Abstract
A critical **Stored XSS** vulnerability exists in the SureForms plugin. The vulnerability stems from an insecure client-side implementation in `entries.js` where user input is programmatically **decoded** (reversing server-side sanitization) and then rendered using `dangerouslySetInnerHTML` without proper client-side sanitization. This allows unauthenticated attackers to inject malicious JavaScript payloads via standard form fields, bypassing WordPress's default `wp_kses` filters.

## 2. Version Identification
To verify if a target site is running SureForms, inspect the translation file header which typically contains the version number.

**Target URL:**
`http://target-site.com/wp-content/plugins/sureforms/languages/sureforms.pot`

**Verification Command:**
```bash
curl -s "http://target-site.com/wp-content/plugins/sureforms/languages/sureforms.pot" | grep "Project-Id-Version"
```

## 3. Reverse Engineering & Root Cause Analysis

The vulnerability resides in the React-based admin interface responsible for viewing form entries (`entries.js`).

### 3.1. The "Auto-Decoder" Logic (The Bypass)
In the minified `entries.js` file, there is a helper function (identified as `Xv` in the analyzed build) designed to handle HTML entities.

**Code Logic (Reconstructed):**
```javascript
// Function Xv: Pre-processing field values
var Xv = function(input) {
    var value = input.value;
    
    // VULNERABILITY ROOT CAUSE:
    // If the string contains HTML entities (e.g., <), create a textarea,
    // inject the content, and extract the value. 
    // This effectively DECODES HTML entities back to raw HTML tags.
    // Example: "<img ...>" becomes ""
    
    if (typeof value === "string" && value.match(/&[a-zA-Z0-9#]+;/)) {
        var textarea = document.createElement("textarea");
        textarea.innerHTML = value;
        
        // Logic to revert sanitization
        if (textarea.value.includes("<") || textarea.value.includes(">")) {
             value = textarea.value; // Now 'value' contains RAW HTML
        }
    }
    return { ...input, value: value };
}
```
**Analysis:** This function defeats backend security. Even if WordPress correctly stores `` as `<script>` in the database, this function converts it back to `` immediately after fetching it from the API.

### 3.2. The Dangerous Sink
After decoding, the data is passed to the rendering component (identified as `Jv`).

**Code Logic (Reconstructed):**
```javascript
// Function Jv: Rendering the field
var Jv = function(props) {
    var field = props.field;
    var val = field.value; // This value is now raw HTML (post-decoding)

    // THE TRIGGER: Check if the string looks like HTML
    if (typeof val === "string" && val.match(/]+>/g)) {
        // THE SINK: Render using dangerouslySetInnerHTML WITHOUT client-side sanitization (e.g., DOMPurify)
        return React.createElement("span", {
            dangerouslySetInnerHTML: { __html: val }
        });
    }
    
    // Safe render for non-HTML text
    return React.createElement("span", null, val);
}
```

## 4. Attack Flow

1.  **Injection:** An unauthenticated attacker submits a form on the frontend. Instead of using raw HTML tags (which would be stripped/sanitized by WordPress backend), the attacker sends **HTML Entities**.
2.  **Storage:** WordPress sees the input (e.g., `<img...`) as safe text and stores it in the database.
3.  **Execution (The Trap):**
    *   The Admin navigates to **SureForms > Entries**.
    *   The browser fetches the entry details via JSON API.
    *   The `Xv` function detects the entities and decodes `<img...` back to ` **Entries**.
3. Click on the entry submitted in Step 1 to view details.

4. **Result:** The browser will execute the JavaScript payload (`alert('XSS_SUREFORMS')`).