Automated Threat Modeling

GPTranslate WordPress Plugin CVE-2026-9109: Brief Summary of Unauthenticated Stored XSS via Exposed API Key and REST API

A short review of CVE-2026-9109, an unauthenticated stored XSS vulnerability in the GPTranslate WordPress plugin (versions up to 2.31). The attack uses a deterministically derived API key that the plugin exposes on every page. Covers the patch details and the affected versions.

CVE Analysis

10 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-06-12

GPTranslate WordPress Plugin CVE-2026-9109: Brief Summary of Unauthenticated Stored XSS via Exposed API Key and REST API
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A deterministically derived API key printed in the HTML source of every WordPress page turns out to be a remarkably effective way to hand unauthenticated attackers the keys to persistent script injection. CVE-2026-9109 in the GPTranslate plugin for WordPress shows how one architectural shortcut, a predictable secret paired with missing output sanitization, can collapse the entire authentication and input validation model of a REST API endpoint.

GPTranslate is an AI-powered multilingual translation plugin for WordPress developed by JExtensions Store. It uses multiple AI models (ChatGPT, Gemini, DeepSeek, Google AI) to translate website content automatically and currently has 500+ active WordPress installations. The install base is modest, but the plugin belongs to a growing market segment, and AI-driven translation tools are gaining traction across CMS platforms.

Technical Information

Root Cause: Two Flaws, One Exploit Chain

CVE-2026-9109 is classified under CWE-79: Improper Neutralization of Input During Web Page Generation and carries a CVSS 3.1 score of 7.2 (High) with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N. It comes from two distinct flaws that work together:

Flaw 1: Deterministic API Key Exposed Client Side. The plugin generates its API key by computing sha256(site_url). It then writes this value into the HTML source of every page on the site in a JavaScript variable called gptApiKey. Because the site URL is public knowledge and the derivation is deterministic, any anonymous visitor can view the page source, read the gptApiKey value, and use it to authenticate against the plugin's REST API. The code responsible is at gptranslate.php line 1134 in versions up to 2.31.

Flaw 2: Insufficient Input Sanitization and Output Escaping. The plugin's REST API endpoint at /wp-json/gptranslate/v1/request accepts translation payloads and stores them in the database without adequate sanitization. When the plugin later renders these stored translations, its JavaScript uses raw innerHTML assignments (referenced in admin.js), so any script tags or event handlers in the translation data execute directly in the browser. On the server side, the plugin injects JSON data containing translation records into admin page <script> blocks without proper encoding, which gives an attacker a second way to break out of the script context.

Attack Flow

The exploitation path requires no authentication, no user interaction, and no specialized conditions:

Step 1: API Key Extraction. The attacker visits any page on the target WordPress site and inspects the HTML source. The gptApiKey JavaScript variable contains the SHA-256 hash of the site URL. The attacker could also compute this value from the public site URL, but reading it from the page source is simpler.

Step 2: Malicious Payload Submission. Using the extracted API key, the attacker crafts an HTTP request to /wp-json/gptranslate/v1/request with JavaScript payloads embedded in the translation content. The endpoint treats the request as authenticated because the attacker supplies the correct (publicly visible) API key.

Step 3: Persistent Storage. The plugin stores the attacker's translation payload in the WordPress database without sanitizing it. The malicious script now sits alongside legitimate translation data.

Step 4: Payload Execution. When any user (administrator, editor, or front-end visitor) opens a page that renders the stored translation, the injected JavaScript executes in their browser context. Because the plugin uses innerHTML to render translation content, the browser parses and executes the embedded scripts. This is a stored (Type 2) XSS attack, in which the payload persists on the server and fires for every subsequent visitor.

CVSS Metric Breakdown

CVSS MetricValueSignificance
Attack Vector (AV)NetworkExploitable remotely over the internet
Attack Complexity (AC)LowNo specialized conditions required
Privileges Required (PR)NoneNo authentication needed
User Interaction (UI)NoneNo victim interaction needed for injection
Scope (S)ChangedImpact crosses security boundaries
Confidentiality (C)LowLimited information disclosure possible
Integrity (I)LowLimited modification of data possible
Availability (A)NoneNo direct availability impact

Scope is assessed as "Changed" rather than "Unchanged" because the flaw sits in the plugin's REST API (the vulnerable component), while the script executes in the victim's browser, which is a different security authority.

Impact

The consequences follow the standard impact model for persistent script injection:

  • Session token theft via cookie exfiltration
  • Unauthorized actions performed in the context of authenticated users, including administrators
  • Redirection to malicious sites
  • Keylogging
  • Potential lateral movement if an administrator session is compromised

Because the XSS is stored, a single injection can reach every subsequent visitor to the affected page, so one malicious request can lead to mass compromise.

Discovery and Disclosure

Security researchers mrholmes and papadope discovered the vulnerability and disclosed it through Wordfence's coordinated vulnerability reporting program ([email protected]). It was published on June 12, 2026, and the NVD entry followed on June 13, 2026.

Patch Information

The GPTranslate developer released version 2.32 on May 22, 2026. It addresses CVE-2026-9109 with four distinct security improvements, layered for defense in depth. The Wordfence advisory marks the vulnerability as "Patched" and gives the remediation as updating to version 2.32 or later. The vendor changelog documents these changes:

1. Safe DOM APIs replacing innerHTML. This is the most direct fix for the stored XSS. In versions up to 2.31, the admin translation editor rendered translation and alt-translation records with raw innerHTML assignments, so any script tags or event handlers stored in translation data would execute in the browser. The patch switches these rendering paths to safe DOM APIs (such as textContent or DOM element creation methods), which treat the content as plain text rather than executable markup. The Wordfence advisory references changes between tags/2.31/assets/js/admin.js and tags/2.32/assets/js/admin.js that correspond to this front-end rendering fix.

2. JSON_HEX_TAG escaping for server-side output. In the vulnerable version, the plugin injected JSON data containing translation records directly into admin page <script> blocks without proper encoding. An attacker's payload containing </script> could break out of the script context entirely. The patch applies PHP's JSON_HEX_TAG flag when encoding this data. The flag converts < and > to their Unicode escape sequences (\u003C, \u003E), so no payload can break out of the script context. The Wordfence advisory cites changes at gptranslate.php around lines 3574 to 3578 for this fix.

3. Cryptographically random API secret. This architectural change is the one that eliminates the unauthenticated attack vector. In versions up to 2.31, the API key protecting the REST endpoint was derived deterministically as sha256(site_url) and printed on every page in the gptApiKey JavaScript variable. The patch replaces this predictable key with a cryptographically random secret that is generated and stored in the WordPress database and no longer appears in the HTML output. This change is referenced at gptranslate.php line 1104 (patched) vs. line 1134 (vulnerable).

4. WordPress nonce verification on REST write operations. As a further defense-in-depth measure, the patch adds WordPress nonce verification, and with it CSRF protection, to the storetranslations and syncTranslation REST write endpoints. Even if an attacker somehow obtained a valid API secret, they would also need a valid, session-bound nonce to submit translation payloads.

Recommended action: Update directly to the latest version (2.33.2) rather than the minimum patched version (2.32). Later releases add more security improvements. Version 2.32.7 hardened the syncTranslation function and patched a separate SQL injection vulnerability (CVE-2026-49776), and version 2.33.2 further improved API key hash storage and validation.

If you cannot patch right away, deactivate and remove the GPTranslate plugin entirely. No configuration makes versions up to 2.31 safe, because the exploitation path has no prerequisites.

Affected Systems and Versions

The vulnerability affects the following:

  • Plugin: GPTranslate (Multilingual AI Translation for WordPress: Automatically Translate Websites)
  • Affected versions: All versions up to and including 2.31
  • Patched version: 2.32 (released May 22, 2026)
  • Latest version: 2.33.2 (released June 11, 2026; recommended)
  • Platform: WordPress
  • Vulnerable component: REST API endpoint /wp-json/gptranslate/v1/request
  • Vulnerable code locations (version 2.31): gptranslate.php lines 1134, 3578, 3654; assets/js/admin.js line 1

Any WordPress site running GPTranslate version 2.31 or earlier is vulnerable regardless of configuration, because the API key exposure and the lack of input sanitization are built into the plugin's design in those versions.

Vendor Security History

JExtensions Store's GPTranslate plugin has accumulated multiple significant vulnerabilities in a narrow version range, which suggests systemic weaknesses in input validation:

CVETypeCVSSAffected VersionsPatched VersionDiscoverer
CVE-2026-9109Unauthenticated Stored XSS7.2Up to 2.312.32mrholmes, papadope
CVE-2026-49776Unauthenticated SQL Injection7.5 (Wordfence) / 9.3 (Patchstack)Up to 2.32.62.32.7Nguyen Dinh Hai (HaiND), PTIT

The SQL injection vulnerability (CVE-2026-49776) affects the syncTranslation function and was documented by both Wordfence and Patchstack. Both vulnerabilities follow the same root cause pattern of trusting user-supplied data without validating it. The XSS indicates missing output encoding, and the SQL injection suggests queries that are not properly parameterized.

The deterministic API key design (the SHA-256 of the site URL, exposed in client-side JavaScript) is a fundamental flaw in the security architecture, not a simple coding error, and it suggests insufficient security review during the plugin's initial design. The vendor has been responsive in releasing patches, and the incremental improvements from 2.32 through 2.33.2 show signs of maturing security practice. Even so, the pattern warrants treating GPTranslate as a higher-risk plugin that needs defense-in-depth measures.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization