One Request to Admin: Three Skipped Auth Checks in Bisheng

Louis Sanchez September 25, 2026 11 min read

The interesting thing about the three bugs we found in Bisheng is not that they exist. It is that they are the same mistake, made three times, in three different files, by developers who clearly knew better. In every case a function that reads or acts on data belonging to a specific user simply skipped the ownership check that its sibling functions, sitting right next to it in the same class, already performed. The write paths were guarded. The read paths were not.

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, that teams use to wire together language models, tools, and knowledge bases. Its own documentation describes multi-tenant, multi-team enterprise deployments as a primary use case, and it ships a commercial "Bisheng Pro" mode with SSO for exactly that setting. That multi-user shape is what turns three skipped checks from a code-quality note into a cross-tenant breach.

The short version

We reported three missing-authorization flaws in Bisheng. The most serious, CVE-2026-96679 (CVSS 9.8), turns a single unauthenticated request into a super-admin session on any instance running with BISHENG_PRO=true — and it is still unpatched. The other two, CVE-2026-96681 (6.5) and CVE-2026-100156 (5.4), let any logged-in user read other users' workflow data and run work against other users' LLM API keys. All three were coordinated through CERT/CC as VU#166125.

The findings at a glance

CVE Issue Severity Fix status (verified 2026-09-25)
CVE-2026-96679 Pre-auth admin takeover via /user/sso 9.8 Critical No fixed version. Legacy endpoint still live on main.
CVE-2026-96681 Cross-user flow/workflow version disclosure (IDOR) 6.5 Medium Fixed in the v3.0.0 line only; every 2.x release remains vulnerable.
CVE-2026-100156 Cross-user assistant LLM credential abuse 5.4 Medium Fixed in v2.5.0 — silently, before disclosure, never documented as security.

Vendor: DataElem, Inc. Affected project: dataelement/bisheng. All three were discovered in a manual source-code audit on May 14, 2026, and reported to the vendor through GitHub Private Vulnerability Reporting on May 23, 2026. There was no SECURITY.md and no security contact; private reporting was the only channel available.

CVE-2026-96679: a flag is not a credential

Bisheng's "Pro" mode is designed to sit behind a separate, closed-source SSO gateway. The idea is that in a production Pro deployment, a trusted front end authenticates users and then tells Bisheng who they are. To support that, the open-source backend exposes an endpoint, POST /user/sso, that accepts a username and issues that user a signed session token.

The problem is the gate on that endpoint. The only thing standing between an anonymous caller and a valid session is a check that BISHENG_PRO is switched on. That is an environment-variable flag, not a credential. There is no shared secret, no signed assertion, no header token, no IP allowlist — nothing that verifies the caller is actually the trusted gateway rather than an anonymous visitor on the internet. The flag is meant to signal that a gateway is present. The code never confirms it.

With the flag on, the endpoint will issue a token for whatever username it is handed. And the account-provisioning logic behind it will, under ordinary first-run or configured-admin-name conditions, mint that session at the super-admin role. The result is that a single unauthenticated request can return a fully privileged administrative token. We are deliberately not publishing the request itself, because there is no fixed version to upgrade to.

Why we are withholding the proof-of-concept

CVE-2026-96679 has no patch as of this writing. Publishing a copy-paste exploit for an unpatched critical would hand attackers a weapon and give defenders nothing they cannot already act on. The mitigations below do not depend on the exact request, and we will not release exploit detail until a fix ships.

What an attacker gets

Super-admin on a Bisheng instance is not a contained prize. It reads as full control of everything the platform touches:

Because Bisheng flow and assistant configurations routinely embed credentials for external systems — LLM providers, internal databases, REST APIs — an admin compromise here tends to chain outward into the connected infrastructure rather than stopping at the platform boundary.

This finding is dormant on default open-source deployments, which ship with BISHENG_PRO=false. It is live on precisely the enterprise Pro deployments the mode exists to serve.

Where it stands today

We re-checked the current dataelement/bisheng main source on September 25, 2026, reading the handler directly rather than trusting commit messages. 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, in the interim, built a properly HMAC-authenticated replacement family of endpoints, and the legacy handler's own docstring now points to it. But the old, unauthenticated endpoint has not been removed, disabled, or gated behind the new check. It is still present and still reachable. No release in either the 2.x or 3.x line remediates it.

If you run Bisheng Pro, do this now

There is no fixed version, so mitigation is the whole game. Only set BISHENG_PRO=true if the deployment is genuinely fronted by a gateway that authenticates callers before they reach /user/sso. Migrate to the newer HMAC-authenticated /api/v1/internal/sso/login-sync endpoints. And as defense in depth, restrict /user/sso so it is reachable only from the gateway, not from general network traffic.

CVE-2026-96681: read any user's workflow, including its secrets

The second bug lives in the flow and workflow service. Bisheng versions a user's flows and workflows, and exposes endpoints to list the versions of a flow and to fetch the full contents of a specific version. Neither of those two read methods checks whether the caller owns, or has any relationship to, the flow they are asking about. The methods are even handed the caller's identity as a parameter — and then never use it.

What makes this more than an abstract information leak is what a version's contents actually hold. A Bisheng flow definition includes the configuration of every node in it: REST, SQL, and GraphQL nodes carry headers, connection strings, and parameters, which in practice frequently means hardcoded credentials. It also includes proprietary system prompts and the linkages between tools, flows, and knowledge bases. The listing path compounds it by returning soft-deleted versions too, so history a user believed they had retracted is still readable.

The tell is right there in the same class. The write operations on flow versions — delete, create, update, change-current — all call an ownership check before they act. Only the two read paths were missing it. Any authenticated account, including a freshly registered default-role user, can enumerate and read another user's workflow versions. In the multi-tenant deployments Bisheng markets to, that is a cross-team credential and intellectual-property exposure. It is read-only, which is why it lands at 6.5 rather than higher.

This one is fixed — but only partly, and in a way worth spelling out. The fix arrived as part of a broad migration to a relationship-based (ReBAC) permission model and first appears in the v3.0.0 line. We verified by reading the source at each release tag, not by tag names or dates: every 2.x release we checked, including the current 2.6.0 patch series, still lacks the check. Teams on the 2.x line, even fully up to date within it, remain exposed. Only moving to the 3.0.0 line closes it, and even there the change was never called out as a security fix.

CVE-2026-100156: running on someone else's dime

The third bug is in the assistant service, in the feature that auto-optimizes an assistant's prompt by running it through that assistant's own configured LLM. The endpoints that queue and stream that optimization took an assistant identifier from the caller and never checked whether the caller owned that assistant.

Two things follow. First, the optimization runs against the target assistant's LLM configuration — which means an attacker can drive inference billed to another user's provider account (OpenAI, Azure, Anthropic), spending their quota and their money on arbitrary prompts. Second, the streamed response describes the victim assistant's configured tools and flows, a smaller information leak that chains naturally with the flow disclosure above. Same structural mistake as the others: the sibling write methods all called the permission check; this read-and-execute path was the one that skipped it.

This is the one the vendor has fully fixed — but the timeline is its own story. The fix landed in v2.5.0, and we confirmed it by reading the source at the tags on either side. Crucially, the fix commit predates our discovery and our report. It was not a response to disclosure. It was incidental collateral from the same large permission-architecture migration DataElem was running that month, which happened to add the missing check while refactoring. From a user's point of view there was never any signal: no changelog entry, no release note, no advisory. The endpoint was quietly vulnerable, and then quietly not.

The pattern worth taking away

Three modules, one recurring gap: a read or execute path that skips the ownership check its neighboring write paths already enforce. If you build multi-tenant software, the lesson is that authorization belongs on every data path, and the fastest place to find where it is missing is to line up the methods that touch the same resource and look for the odd one out. That review takes an afternoon. It is the review that would have caught all three of these.

Disclosure timeline

The vendor did not respond to the reporter or, as far as the coordination record shows, to CERT/CC across the entire window. Two of the three issues picked up fixes anyway — one incidentally before we ever reported it, one only in a still-young major-version line — as byproducts of an unrelated refactor rather than a deliberate security response. The highest-severity issue, the one that matters most, is the one still open.

Advisory references: CERT/CC VU#166125 · CVE-2026-96679 · CVE-2026-96681 · CVE-2026-100156 · GHSA-c2hq-p2mh-q26r · GHSA-5cc6-8jr6-7xfw · GHSA-3pg6-86c3-3jv5 · full technical advisory

What to do if you run Bisheng

Is your platform's authorization actually enforced?

These bugs were not clever. 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. That is the work we do. If you are shipping multi-tenant software and want to know where your ownership checks are missing, let's talk.

Scope a penetration test

More Voke Cyber research: CVE-2026-17613: cross-team file takeover in Penpot · CVE-2026-15630: cross-tenant authorization bypass in Casdoor · the full advisory index.