TextP2P Texting Widget <= 1.7 - Cross-Site Request Forgery to Settings Update
Description
The TextP2P Texting Widget plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to and including 1.7. This is due to missing nonce validation in the imTextP2POptionPage() function which processes settings updates. The form at line 314 does not include a wp_nonce_field(), and the POST handler at line 7 does not call check_admin_referer() or wp_verify_nonce() before processing settings changes. This makes it possible for unauthenticated attackers to update all plugin settings including chat widget titles, messages, API credentials, colors, and reCAPTCHA configuration via a forged request, granted they can trick a site administrator into performing an action such as clicking a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:NTechnical Details
<=1.7This research plan outlines the steps to exploit the Cross-Site Request Forgery (CSRF) vulnerability in the **TextP2P Texting Widget** plugin (CVE-2026-4133). ### 1. Vulnerability Summary The **TextP2P Texting Widget** plugin for WordPress is vulnerable to CSRF in versions up to and including 1.7. …
Show full research plan
This research plan outlines the steps to exploit the Cross-Site Request Forgery (CSRF) vulnerability in the TextP2P Texting Widget plugin (CVE-2026-4133).
1. Vulnerability Summary
The TextP2P Texting Widget plugin for WordPress is vulnerable to CSRF in versions up to and including 1.7. The vulnerability exists in the imTextP2POptionPage() function, which serves both as the display for the settings page and the handler for saving those settings.
The plugin fails to implement any nonce verification. Specifically:
- The HTML form (around line 314) does not include
wp_nonce_field(). - The processing logic at the start of the function (around line 7) does not call
check_admin_referer()orwp_verify_nonce()before updating plugin options based on$_POSTdata.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/options-general.php?page=textp2p-texting-widget(inferred slug based on plugin name). - Vulnerable Action: POST request to the settings page.
- Vulnerable Parameters: Plugin settings such as
textp2p_api_key,textp2p_widget_title,textp2p_widget_message,textp2p_widget_color, andtextp2p_recaptcha_key(inferred). - Authentication Level: Unauthenticated (Attacker) triggers the request through an Authenticated Administrator (Victim).
- Preconditions: An administrator must be logged into the WordPress dashboard and be tricked into visiting a malicious page or clicking a link that submits a POST request to the target site.
3. Code Flow
- Registration: The plugin registers an options page via
add_options_page()oradd_menu_page()in the admin menu, usingimTextP2POptionPageas the callback function. - Execution: When a POST request is sent to the options page, WordPress executes
imTextP2POptionPage(). - Vulnerable Logic (Line 7+):
function imTextP2POptionPage() { if (isset($_POST['submit'])) { // Inferred trigger // MISSING: check_admin_referer('action_name'); update_option('textp2p_api_key', $_POST['textp2p_api_key']); // Inferred // ... updates other settings ... } // ... displays form at Line 314 ... // MISSING: wp_nonce_field('action_name'); } - Sink: The user-controlled
$_POSTdata is passed directly intoupdate_option().
4. Nonce Acquisition Strategy
No nonce is required. The vulnerability is defined by the absolute absence of nonce validation. The attack can be performed as long as the victim administrator has an active session cookie.
5. Exploitation Strategy
The goal is to demonstrate that an administrator's settings can be changed without their consent. We will simulate the CSRF by making an authenticated POST request as an admin using the http_request tool, omitting any nonce.
Step-by-Step Plan:
- Identify Settings Page: Confirm the settings page URL (usually
wp-admin/options-general.php?page=textp2p-texting-widget). - Capture Option Names: Use
wp option listto find options related to "textp2p" to confirm exact parameter names. - Perform CSRF: Submit a POST request to the settings page with malicious values.
- Verification: Use WP-CLI to confirm the database was updated.
HTTP Request Details:
- Tool:
http_request - Method: POST
- URL:
http://[target]/wp-admin/options-general.php?page=textp2p-texting-widget - Headers:
Content-Type: application/x-www-form-urlencoded
- Body (URL Encoded):
(Note: Parameter names liketextp2p_api_key=EXPLOITED_API_KEY&textp2p_widget_title=Hacked+by+CSRF&submit=Save+Changestextp2p_api_keyare inferred and should be verified viawp option listor by inspecting the HTML source of the settings page first.)
6. Test Data Setup
- Install Plugin: Ensure
textp2p-texting-widgetversion <= 1.7 is installed and active. - Create Admin: A standard administrator user must exist (usually created by default in the test environment).
- Initial State: Set a legitimate-looking API key using WP-CLI:
wp option update textp2p_api_key "LEGIT_API_KEY_12345"
7. Expected Results
- The
http_requestshould return a302 Redirector a200 OK(depending on how the plugin redirects after saving). - The response should NOT contain any error related to "invalid nonce" or "link has expired."
- The plugin options in the database should be updated to the attacker-supplied values.
8. Verification Steps
After the http_request, run the following WP-CLI commands:
- Check the API Key:
wp option get textp2p_api_key
Expected output:EXPLOITED_API_KEY - Check the Widget Title:
wp option get textp2p_widget_title
Expected output:Hacked by CSRF
9. Alternative Approaches
If the plugin uses a different slug or a dedicated AJAX handler:
- Inspect HTML: Use
browser_navigateto the settings page and usebrowser_eval("document.querySelector('form').action")to find the exact target URL. - Verify Parameters: Use
browser_evalto extract allinputnames from the form:browser_eval("Array.from(document.querySelectorAll('input[name]')).map(i => i.name)") - AJAX Check: If the form saves via AJAX, look for
wp_ajax_hooks in the code and targetadmin-ajax.phpinstead of the settings page URL. The CVSS description explicitly points to the settings page function (imTextP2POptionPage), making the form POST the most likely vector.
Summary
The TextP2P Texting Widget plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to and including 1.7. This occurs because the plugin's settings page handler, imTextP2POptionPage(), lacks nonce validation, allowing attackers to modify critical settings like API keys and widget configurations by tricking an administrator into making a forged request.
Vulnerable Code
// File: textp2p-texting-widget.php (approximate) // Line 7: Settings update logic starts without security checks function imTextP2POptionPage() { if (isset($_POST['submit'])) { update_option('textp2p_api_key', $_POST['textp2p_api_key']); update_option('textp2p_widget_title', $_POST['textp2p_widget_title']); // ... other options updated without nonce verification ... } --- // Line 314: Form display logic lacks wp_nonce_field() ?> <form method="post" action=""> <input type="text" name="textp2p_api_key" value="<?php echo get_option('textp2p_api_key'); ?>"> <input type="submit" name="submit" value="Save Changes"> </form> <?php }
Security Fix
@@ -5,6 +5,9 @@ function imTextP2POptionPage() { - if (isset($_POST['submit'])) { + if (isset($_POST['submit'])) { + if (!isset($_POST['textp2p_nonce']) || !wp_verify_nonce($_POST['textp2p_nonce'], 'textp2p_save_settings')) { + wp_die('Security check failed'); + } update_option('textp2p_api_key', $_POST['textp2p_api_key']); @@ -314,6 +317,7 @@ <form method="post" action=""> + <?php wp_nonce_field('textp2p_save_settings', 'textp2p_nonce'); ?> <input type="text" name="textp2p_api_key" value="<?php echo get_option('textp2p_api_key'); ?>">
Exploit Outline
The exploit targets the plugin's settings administration page. An attacker identifies the settings page at /wp-admin/options-general.php?page=textp2p-texting-widget. Since the imTextP2POptionPage function does not perform any nonce validation (no check_admin_referer or wp_verify_nonce calls) and the form does not include a hidden nonce field, the attacker can construct a malicious HTML page. This page contains a self-submitting POST form targeting the plugin's settings page with parameters such as 'textp2p_api_key' and 'textp2p_widget_title' set to attacker-controlled values. When an authenticated site administrator visits the attacker's page, the browser automatically sends the POST request with the administrator's active session cookies, resulting in the plugin updating its configuration with the attacker's data.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.