Filr – Secure document library <= 1.2.11 - Authenticated (Administrator+) Stored Cross-Site Scripting via HTML Upload
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:NTechnical Details
<=1.2.11Source Code
WordPress.org SVNThis 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_fileor a handler tied to theFILR_Uploaderclass. - Vulnerable Parameter: The
filefield in amultipart/form-datarequest. - Authentication: Authenticated as Administrator (or any role with
edit_filrpermissions). - Preconditions: The plugin must be active, and a user must have access to the
filrCustom Post Type (CPT) editor.
3. Code Flow (Inferred)
- Entry Point: An admin navigates to Filr > Add New or edits an existing
filrpost. - UI Trigger: The admin uses the "Upload" button. This triggers a JavaScript-based uploader (likely using Plupload or the WordPress Media framework).
- AJAX Request: The JS sends a request to
admin-ajax.phpwith an action handled byFILR_Uploader. - Processing:
FILR_Uploader::upload()(inferred) receives the file. It likely useswp_handle_upload(). - The Flaw: The
$overridespassed towp_handle_upload()do not restrict thetest_typeor provide amimesfilter that excludestext/html. - Storage: The file is saved to the uploads directory (e.g.,
wp-content/uploads/filr/). - 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.
- Identify Shortcode/Page: The upload interface exists within the WordPress Admin dashboard for the
filrpost type. - Access Editor: Navigate to
wp-admin/post-new.php?post_type=filr. - Variable Discovery: The plugin likely localizes script data.
- 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, orfilr_uploader. - Use
browser_evalto 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-nonceor similar, but Filr often uses its own uploader class.
- Navigate to the "Add New Filr" page using
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_uploadorfilr_file_upload._wpnonce: The nonce extracted in step 4.file: The content ofxss.html.post_id: (Optional) ID of thefilrpost 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, orfile_url.
Step 4: Trigger XSS
Navigate to the returned URL in the browser.
6. Test Data Setup
- Active Plugin: Ensure
filr-protectionis installed and activated. - Admin User: Log in as a user with
administratorrole. - 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.phprequest should return a200 OKwith 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:
- Check Filesystem:
ls -la /var/www/html/wp-content/uploads/filr/ | grep xss.html - Check Post Meta:
Identify the metadata associated with thefilrpost 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:
- Form Submission: Intercept the form at
wp-admin/post.phpwhen saving afilrpost. - 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_scripton 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.
- If a frontend upload exists, the nonce might be available via
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
@@ -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.