CVE-2025-14632

Filr – Secure document library <= 1.2.11 - Authenticated (Administrator+) Stored Cross-Site Scripting via HTML Upload

mediumUnrestricted Upload of File with Dangerous Type
4.4
CVSS Score
4.4
CVSS Score
medium
Severity
1.2.12
Patched in
1d
Time to patch

Description

The Filr – Secure document library plugin for WordPress is vulnerable to Stored Cross-Site Scripting via unrestricted file upload in all versions up to, and including, 1.2.11 due to insufficient file type restrictions in the FILR_Uploader class. This makes it possible for authenticated attackers, with Administrator-level access and above, to upload malicious HTML files containing JavaScript that will execute whenever a user accesses the uploaded file, granted they have permission to create or edit posts with the 'filr' post type.

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<=1.2.11
PublishedJanuary 16, 2026
Last updatedJanuary 17, 2026
Affected pluginfilr-protection

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to verify the Authenticated (Administrator+) Stored Cross-Site Scripting (XSS) vulnerability in the **Filr – Secure document library** plugin (CVE-2025-14632). --- ### 1. Vulnerability Summary The `FILR_Uploader` class in the Filr plugin fails to implement suf…

Show full research plan

This research plan outlines the steps to verify the Authenticated (Administrator+) Stored Cross-Site Scripting (XSS) vulnerability in the Filr – Secure document library plugin (CVE-2025-14632).


1. Vulnerability Summary

The FILR_Uploader class in the Filr plugin fails to implement sufficient file type restrictions during document uploads. While the plugin is designed to manage "secure" document libraries, it does not explicitly block HTML files from being uploaded as library items. An attacker with Administrator (or lower, if given filr post type permissions) access can upload a malicious .html file. Because WordPress (and the plugin) serves these files directly or via a wrapper that does not strip script tags, the JavaScript within the HTML executes in the context of the site when viewed.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php (inferred uploader hook).
  • Action: Likely filr_upload_file or a handler tied to the FILR_Uploader class.
  • Vulnerable Parameter: The file field in a multipart/form-data request.
  • Authentication: Authenticated as Administrator (or any role with edit_filr permissions).
  • Preconditions: The plugin must be active, and a user must have access to the filr Custom Post Type (CPT) editor.

3. Code Flow (Inferred)

  1. Entry Point: An admin navigates to Filr > Add New or edits an existing filr post.
  2. UI Trigger: The admin uses the "Upload" button. This triggers a JavaScript-based uploader (likely using Plupload or the WordPress Media framework).
  3. AJAX Request: The JS sends a request to admin-ajax.php with an action handled by FILR_Uploader.
  4. Processing: FILR_Uploader::upload() (inferred) receives the file. It likely uses wp_handle_upload().
  5. The Flaw: The $overrides passed to wp_handle_upload() do not restrict the test_type or provide a mimes filter that excludes text/html.
  6. Storage: The file is saved to the uploads directory (e.g., wp-content/uploads/filr/).
  7. Execution: The admin/user accesses the document's direct URL or the Filr library frontend.

4. Nonce Acquisition Strategy

Since this is an authenticated admin-side upload, a nonce will be required.

  1. Identify Shortcode/Page: The upload interface exists within the WordPress Admin dashboard for the filr post type.
  2. Access Editor: Navigate to wp-admin/post-new.php?post_type=filr.
  3. Variable Discovery: The plugin likely localizes script data.
  4. Nonce Extraction:
    • Navigate to the "Add New Filr" page using browser_navigate.
    • Search the page source for localized objects. Common names in this plugin: filr_vars, filr_admin, or filr_uploader.
    • Use browser_eval to extract the nonce:
      // Example guess based on common plugin patterns
      window.filr_vars?.nonce || window.filr_admin_opts?.upload_nonce
      
    • Note: If the uploader uses the standard WordPress media library, the nonce will be wp-stateless-nonce or similar, but Filr often uses its own uploader class.

5. Exploitation Strategy

The goal is to upload an HTML file and confirm it can be executed.

Step 1: Preparation
Create a malicious HTML file named xss.html:

<html>
<body>
<h1>PoC</h1>
<script>alert(document.domain + " - CVE-2025-14632");</script>
</body>
</html>

Step 2: Upload via HTTP Request
Send a POST request to admin-ajax.php.

  • URL: https://target.local/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: multipart/form-data
  • Parameters:
    • action: (Inferred) filr_upload or filr_file_upload.
    • _wpnonce: The nonce extracted in step 4.
    • file: The content of xss.html.
    • post_id: (Optional) ID of the filr post being created/edited.

Step 3: Retrieve File Path
The AJAX response should return a JSON object containing the URL of the uploaded file.

  • Expected JSON key: url, data.url, or file_url.

Step 4: Trigger XSS
Navigate to the returned URL in the browser.

6. Test Data Setup

  1. Active Plugin: Ensure filr-protection is installed and activated.
  2. Admin User: Log in as a user with administrator role.
  3. Custom Post Type: If the plugin requires a document library to be created first, create one via WP-CLI:
    wp post create --post_type=filr --post_title="XSS Library" --post_status=publish
    

7. Expected Results

  • The admin-ajax.php request should return a 200 OK with a success status.
  • The file should be accessible at a URL like https://target.local/wp-content/uploads/filr/xss.html.
  • Visiting the URL should trigger a browser alert box showing the site's domain.

8. Verification Steps

After the HTTP exploit, verify the file exists on the filesystem and is correctly associated with the plugin:

  1. Check Filesystem:
    ls -la /var/www/html/wp-content/uploads/filr/ | grep xss.html
    
  2. Check Post Meta:
    Identify the metadata associated with the filr post to see how it stores the file reference:
    wp post list --post_type=filr
    wp post meta list <POST_ID>
    

9. Alternative Approaches

If the FILR_Uploader is not used via AJAX but through a standard form submission:

  1. Form Submission: Intercept the form at wp-admin/post.php when saving a filr post.
  2. Direct Upload: Some versions of Filr allow frontend uploads via shortcodes. Check for shortcodes like [filr_upload] or [filr_library].
    • If a frontend upload exists, the nonce might be available via wp_localize_script on the public page where the shortcode is embedded.
    • Create a page: wp post create --post_type=page --post_content='[filr_library]' --post_status=publish.
    • Extract nonce from that public page.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Filr – Secure document library plugin for WordPress is vulnerable to Stored Cross-Site Scripting via unrestricted file uploads in the FILR_Uploader class. Authenticated administrators can upload malicious HTML files that execute JavaScript in the browser context of any user who accesses the uploaded document.

Security Fix

--- a/inc/classes/class-filr-uploader.php
+++ b/inc/classes/class-filr-uploader.php
@@ -50,7 +50,20 @@
-        $overrides = array('test_form' => false);
+        $overrides = array(
+            'test_form' => false,
+            'mimes'     => array(
+                'pdf'  => 'application/pdf',
+                'zip'  => 'application/zip',
+                'doc'  => 'application/msword',
+                'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+                'xls'  => 'application/vnd.ms-excel',
+                'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+                'png'  => 'image/png',
+                'jpg'  => 'image/jpeg',
+                'jpeg' => 'image/jpeg',
+                'gif'  => 'image/gif',
+            )
+        );
         $movefile = wp_handle_upload($file, $overrides);

Exploit Outline

An attacker with Administrator credentials (or permissions to edit 'filr' posts) navigates to the Filr document library editor to obtain an upload nonce from the localized JavaScript data (e.g., 'filr_vars'). The attacker then submits a multipart/form-data POST request to 'wp-admin/admin-ajax.php' targeting the plugin's upload action. The payload consists of an HTML file containing a malicious script (e.g., <script>alert(1)</script>). Because the plugin does not restrict the 'mimes' parameter in the 'wp_handle_upload' call, the file is accepted and stored in the uploads directory. The attacker then accesses the direct URL of the uploaded HTML file to execute the stored JavaScript.

Check if your site is affected.

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