CVE-2026-96679: Pre-Authentication Admin Takeover in Bisheng via /user/sso
| CVEs | CVE-2026-96679 (this advisory) • CVE-2026-96681 • CVE-2026-100156 |
|---|---|
| Advisories | GHSA-c2hq-p2mh-q26r (SSO bypass) • GHSA-5cc6-8jr6-7xfw (flow IDOR) • GHSA-3pg6-86c3-3jv5 (assistant abuse) |
| CERT/CC | VU#166125 |
| Severity | Critical CVSS v3.1 base score 9.8 (CVE-2026-96679) |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Weaknesses | CWE-306 — Missing Authentication for Critical Function • CWE-287 — Improper Authentication • CWE-290 — Authentication Bypass by Spoofing |
| Product | Bisheng (dataelement/bisheng), open-source enterprise LLM application / RAG platform. Vendor: DataElem, Inc. |
| Affected | CVE-2026-96679 affects any instance running with BISHENG_PRO=true; live at main HEAD as re-verified 2026-09-25. |
| Fixed in | No fix available for CVE-2026-96679. See the per-CVE table for the other two. |
| Reported by | Louis Sanchez — Voke Cyber |
| Coordination | Reported to the vendor 2026-05-23 via GitHub Private Vulnerability Reporting; CERT/CC coordinated (VU#166125) after no vendor response. |
No patch available for the critical
As of publication there is no fixed release for CVE-2026-96679. The legacy /user/sso endpoint was re-verified live at dataelement/bisheng main HEAD on 2026-09-25 by reading the handler source directly. Operators running Pro mode should apply the interim mitigations below immediately. We are withholding the proof-of-concept request until a fixed release exists.
Summary
A manual source audit of Bisheng found the same authorization mistake in three different places: a read or execute path that skips the ownership check its sibling write paths already enforce. The most serious, CVE-2026-96679, is worse than an IDOR: the legacy /user/sso endpoint issues a signed session token for any username it is handed when BISHENG_PRO=true, gated only by an environment-variable flag rather than any caller authentication. One unauthenticated request returns a super-admin token. Two lower-severity cross-user data-disclosure flaws (CVE-2026-96681 and CVE-2026-100156) complete the set. All three were coordinated through CERT/CC as VU#166125.
The three findings
| CVE | Class | CVSS | Fix status (verified 2026-09-25) |
|---|---|---|---|
| CVE-2026-96679 | Missing authentication — pre-auth admin takeover via /user/sso | 9.8 | No fixed version. Legacy endpoint still live on main. |
| CVE-2026-96681 | Missing authorization — cross-user flow/workflow version disclosure (IDOR) | 6.5 | Fixed in the v3.0.0 line only; every 2.x release remains vulnerable. |
| CVE-2026-100156 | Missing authorization — cross-user assistant LLM credential abuse | 5.4 | Fixed in v2.5.0 — silently, before disclosure, never documented as a security fix. |
Background
Bisheng is an open-source, enterprise-grade platform for building LLM applications: a RAG workflow builder and agent platform, typically self-hosted on Kubernetes or Docker. Teams use it to wire together language models, tools, and knowledge bases. Its documentation describes multi-tenant, multi-team enterprise deployments as a primary use case, and it ships a commercial "Bisheng Pro" mode with SSO integration for that setting. That multi-user deployment shape is what gives these authorization gaps their blast radius: the data one user stores — flows, assistants, knowledge bases, and the credentials embedded in them — is meant to be private from the next user on the same instance.
CVE-2026-96679 — root cause: a flag is not a credential
Bisheng Pro is designed to sit behind a separate, closed-source SSO gateway that authenticates users and then tells Bisheng who they are. To support that, the open-source backend exposes POST /user/sso (handled in src/backend/bisheng/user/api/user.py), which accepts a username and returns a signed session token for that user.
The only gate on that endpoint is a check that Pro mode is enabled:
# /user/sso handler (simplified) if settings.get_system_login_method().bisheng_pro: # proceed with SSO login / user creation, then issue a signed JWT # No shared secret. No signed assertion. No header token. No IP allowlist.
That is an environment-variable flag, not a credential. BISHENG_PRO=true is meant to signal that a trusted gateway fronts the server; the code never verifies that the caller actually is that gateway. With the flag on, the endpoint issues a token for whatever username it is given, and the account-provisioning logic behind it will, under ordinary first-user or configured-admin-name conditions, create and return that session at the super-admin role — with no password, no session, and no prior authentication step. A single unauthenticated request can therefore return a fully privileged administrative token.
Even where the requested username is not an admin, the endpoint still creates a regular account and issues it a valid session, which is an unauthenticated account-creation primitive usable for spam or persistence on its own.
Proof-of-concept withheld
Because CVE-2026-96679 has no fixed release, we are holding back the exact request and the token-confirmation steps until a fix ships. The root cause and the mitigations below are what operators need to assess exposure and act; the drop-in exploit is not.
Impact
Super-admin on a Bisheng instance reads as full control:
- Confidentiality (High): every user's flows, workflows, and assistants; every knowledge base; and every LLM-provider API key configured anywhere on the instance.
- Integrity (High): create, modify, or delete any user, flow, assistant, knowledge base, or system setting.
- Availability (High): delete administrators, lock out users, wipe knowledge bases.
Because Bisheng flow and assistant configs routinely embed credentials for external systems (LLM providers, internal databases, REST APIs), admin compromise here typically chains outward into connected infrastructure rather than stopping at the platform boundary.
Pre-conditions
- BISHENG_PRO=true set in the runtime environment.
- Network reachability to /user/sso.
Default open-source instances ship with BISHENG_PRO=false, where this is dormant. It is live on exactly the enterprise Pro deployments the mode exists to serve.
Status at publication
Re-verified against dataelement/bisheng main HEAD on 2026-09-25, reading the handler source directly. The legacy endpoint's behavior is unchanged: it still issues a token for a supplied username with no caller authentication when Pro mode is on. The vendor has since built a properly HMAC-authenticated replacement family of endpoints (/api/v1/internal/sso/login-sync), and the legacy handler's own docstring now points to it — but the original unauthenticated endpoint has not been removed, disabled, or gated behind the new check. No release in the 2.x or 3.x line remediates it.
Interim mitigation (no fixed version exists)
Do not set BISHENG_PRO=true unless the deployment is genuinely fronted by a gateway that authenticates callers before they reach /user/sso. Migrate to the HMAC-authenticated /api/v1/internal/sso/login-sync endpoints. As defense in depth, bind /user/sso to the gateway path only, not to general network traffic.
CVE-2026-96681 — cross-user flow/workflow version disclosure
Bisheng versions a user's flows and workflows and exposes endpoints to list the versions of a flow and to fetch a specific version's contents (in src/backend/bisheng/api/services/flow.py). Neither read method checks whether the caller has any relationship to the flow they are requesting — the methods are even passed the caller's identity and never use it:
# get_version_list_by_flow / get_version_info (simplified) def get_version_info(cls, user, version_id): data = FlowVersionDao.get_version_by_id(version_id) # user is never checked return resp_200(data=data)
The sibling write methods in the same class — delete, create, update, change-current — all call an ownership check before acting. Only the two read paths omit it. The listing path compounds it by returning soft-deleted versions too (include_delete=True), exposing history a user believed was retracted.
What is exposed in a version definition is not trivial: REST, SQL, and GraphQL node configs carry headers, connection strings, and parameters, which in practice frequently include hardcoded credentials; alongside proprietary system prompts and the linkages between tools, flows, and knowledge bases. Any authenticated account, including a freshly-registered default-role user, can enumerate and read another user's workflow versions given a flow or version id. It is read-only, which places it at CVSS 6.5 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N), CWE-862 with CWE-639 and CWE-200.
Fix status: verified by reading source at each release tag. The fix arrived as part of a migration to a relationship-based (ReBAC) permission model and first appears in the v3.0.0 line (confirmed at v3.0.0-beta1 and current main). Every 2.x release checked, including the latest 2.6.0 patch tag, still lacks the check. Teams on the 2.x line remain exposed, and the change was never called out as a security fix.
CVE-2026-100156 — cross-user assistant LLM credential abuse
The assistant service's prompt auto-optimization feature (auto_update_stream in src/backend/bisheng/api/services/assistant.py) took an assistant id from the caller and never checked ownership before running the optimization against that assistant's configured LLM:
# auto_update_stream (simplified) assistant = AssistantDao.get_one_assistant(assistant_id) # no ownership check auto_agent = AssistantAgent(assistant, '', login_user.user_id) await auto_agent.init_auto_update_llm() # loads the victim's LLM + API key
The sibling write methods (update_prompt, update_flow_list, update_tool_list) all call check_update_permission first. This read-and-execute path was the outlier. The consequence: an attacker can drive LLM inference billed to another user's provider account, and the streamed response describes the victim assistant's tools and flows. That is CVSS 5.4 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L), CWE-862.
Fix status: fixed in v2.5.0, confirmed by reading source at the tags on either side. Notably, the fix commit predates both our discovery (2026-05-14) and our report (2026-05-23) — it was incidental collateral from the same permission-architecture migration, not a response to disclosure. No changelog entry, release note, or advisory ever framed it as a security fix.
One pattern, three times
Across three modules — user/SSO, flow, assistant — the same gap recurs: a read or execute path that skips the ownership check its neighboring write paths already enforce. For anyone building multi-tenant software, the takeaway is that authorization belongs on every data path, and the fastest way to find where it is missing is to line up the methods that touch the same resource and look for the odd one out.
Disclosure timeline
- 2026-05-14Manual source-code audit of Bisheng identifies all three missing-authorization issues.
- 2026-05-23All three reported to DataElem via GitHub Private Vulnerability Reporting (GHSA-c2hq-p2mh-q26r, GHSA-5cc6-8jr6-7xfw, GHSA-3pg6-86c3-3jv5). No SECURITY.md or security contact existed; PVR was the only channel.
- 2026-06-1826 days elapsed with no vendor response. Reports prepared for CERT/CC coordination.
- 2026-07-28CERT/CC receives the bundled report and opens case VU#166125.
- 2026-08-19With vendor silence continuing, CERT/CC opens its own coordinating advisory covering the still-live issues, crediting the finder.
- 2026-09-03CVE-2026-96679 and CVE-2026-96681 assigned. Full technical detail supplied to the case.
- 2026-09-21Public-disclosure floor for the vulnerability note.
- 2026-09-25CVE-2026-100156 assigned for the third finding. Patch status re-verified against upstream source: the critical remains unpatched.
The vendor did not respond to the reporter or, as far as the coordination record shows, to CERT/CC across the window. Two of the three issues picked up fixes anyway, as byproducts of an unrelated refactor rather than a deliberate security response. The highest-severity issue is the one still open.
References
- CVE-2026-96679 — SSO pre-auth admin takeover (this advisory)
- CVE-2026-96681 — flow/workflow version IDOR
- CVE-2026-100156 — assistant LLM credential abuse
- CERT/CC VU#166125 — coordination case (vulnerability note pending publication at kb.cert.org/vuls/id/166125)
- GHSA-c2hq-p2mh-q26r • GHSA-5cc6-8jr6-7xfw • GHSA-3pg6-86c3-3jv5 — GitHub advisories (SSO bypass, flow IDOR, assistant abuse)
Is your platform's authorization actually enforced?
These were not clever bugs. They were checks that existed on some code paths and not others — the kind of gap a manual, source-aware review finds and an automated scan walks straight past. If you are shipping multi-tenant software and want to know where your ownership checks are missing, that is the work we do.
Scope a penetration testRead how we found it: One Request to Admin: Three Skipped Auth Checks in Bisheng. More advisories: the full index.