---
id: "CVE-2026-109287"
page: "https://infrastack.ai/live/CVE-2026-109287"
kind: "vulnerability"
aliases: ["CVE-2026-109287", "GHSA-jx3w-3pqq-7f3w"]
title: "Directory structure of inaccessible knowledge bases disclosed via an unscoped directory id"
severity: "medium"
cvss: 5.3
epss: null
exploited: false
status: "open"
category: "ai-tooling"
products: [{"name": "open-webui", "fixed": ["0.11.4"], "affected": ">= 0.9.6, < 0.11.4", "ecosystem": "pypi"}]
ecosystems: ["pypi"]
tags: ["ai-tooling", "cwe-639", "cwe-863", "knowledge-bases", "open-webui", "python", "self-hosted"]
not_affected_if: ["no-knowledge-directories", "version-outside-range"]
published_at: "2026-09-27T19:34:53+00:00"
first_seen_at: "2026-11-09T22:53:28+00:00"
updated_at: "2026-11-09T23:10:12+00:00"
sources: [{"source": "ghsa-repo", "url": "https://github.com/open-webui/open-webui/security/advisories/GHSA-jx3w-3pqq-7f3w", "first_seen_at": "2026-11-09T22:53:28+00:00"}, {"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-109287", "first_seen_at": "2026-11-09T23:10:12+00:00"}]
exploit_sources: []
---

# Directory structure of inaccessible knowledge bases disclosed via an unscoped directory id

Link for people: https://infrastack.ai/live/CVE-2026-109287 (this .md is for agents)

Open WebUI's knowledge base directory endpoints accept a directory id from a different knowledge base, so a user who can read one knowledge base can see the names, parents and owner ids of folders in another. File contents and embeddings of the other knowledge base are not exposed according to the advisory.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- pypi:open-webui affected >= 0.9.6, < 0.11.4 fixed 0.11.4

## How to check

- Check the installed `open-webui` version with `pip show open-webui`; affected versions are `>= 0.9.6` and `< 0.11.4`.
- Confirm whether the deployment uses knowledge base directories (the `workspace.knowledge` permission is off by default).

## Fix

- `open-webui` `0.11.4` (fixed in commit a9541c18c; the advisory says upgrading is sufficient)

## Timeline

- 2026-11-09T22:53:28+00:00 ghsa-repo https://github.com/open-webui/open-webui/security/advisories/GHSA-jx3w-3pqq-7f3w
- 2026-11-09T23:10:12+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-109287

## Documents

- [advisory] Maintainer's advisory: github.com https://github.com/open-webui/open-webui/security/advisories/GHSA-jx3w-3pqq-7f3w
- [advisory] Third-party advisory: www.vulncheck.com https://www.vulncheck.com/advisories/open-webui-0.9.6-before-0.11.4-information-disclosure-via-unscoped-directory-id

## From the sources

# Directory structure of inaccessible knowledge bases disclosed via an unscoped directory id

## Summary
A user who can read one knowledge base could list it with the id of a directory that belongs to a different knowledge base they have no access to. The response returned that directory and every parent above it, including folder names and the owning user. The same foreign directory id was also accepted as the parent of a new or moved directory and as the target directory when linking files. None of these paths checked that the directory belonged to the knowledge base named in the request.

## Preconditions
- An account with read access to at least one knowledge base, through a share grant, the `workspace.knowledge` permission (off by default) or the admin role.
- The id of a directory inside a knowledge base the attacker cannot access. Directory ids are random UUIDs and cannot be enumerated, so in practice this is someone who saw them earlier, for example a collaborator whose access was later revoked.
- No configuration flag is involved. Every deployment running an affected version with knowledge base directories carries the code path.

## Impact
With one retained directory id, the attacker reads the current name, id, parent, owner user id, containing knowledge base id and timestamps of that directory and all of its ancestors. Renames made after their access was revoked are also visible. Where folder names encode client, project or case names, that structure is the sensitive part. The id requirement keeps the realistic attacker population small. The write-side paths let the attacker attach their own directories or files under a foreign directory, but this gives them nothing beyond the write access they already hold on their own knowledge base. File contents, file lists and the embeddings of the foreign knowledge base are not exposed.

## Fix
Fixed in a9541c18c. Directory lookups are now bound to the knowledge base in the request: the breadcrumb walk only follows directories of that knowledge base, and every endpoint that accepts a directory or parent id rejects one from another knowledge base. The upload path ignores it. Upgrading is sufficient.

## Root cause
- `backend/open_webui/models/knowledge.py`, `get_directory_breadcrumbs`
- `backend/open_webui/routers/knowledge.py`, `GET /api/v1/knowledge/{id}/files` (`directory_id`), `POST /{id}/dirs/create` and `POST /{id}/dirs/{dir_id}/update` (`parent_id`), `POST /{id}/file/add` and `POST /{id}/files/batch/add` (`directory_id`)
- `backend/open_webui/routers/files.py`, upload auto-link (`metadata.directory_id`)
- Present in every release from 0.9.6, when knowledge base directories were introduced.

Each endpoint checked the caller's access to the knowledge base in the URL and then used the caller-supplied directory id as given. The breadcrumb walk looked directories up by id alone, while the file list and directory list in the same response were filtered by knowledge base. So the one part of the response that followed the caller's id could leave the authorised knowledge base. The create, update and link paths had the same gap, and only the move, delete and sync cleanup paths compared the directory's knowledge base to the one in the URL.

## Proof of concept
Reproduced against the real knowledge router on a fresh database. The admin owns a private knowledge base A with the nested directories `ACME-Litigation/witness-list` and a knowledge base B shared with an ordinary user.

1. As the user, `GET /api/v1/knowledge/{A}/files` returns 400 (no access).
2. As the user, `GET /api/v1/knowledge/{B}/files?directory_id={id of witness-list}` returns 200 with `breadcrumbs` listing `ACME-Litigation` and `witness-list`, each carrying knowledge base A's id and the admin's user id.
3. As the user, `POST /api/v1/knowledge/{B}/dirs/create` with `parent_id` set to a directory of A returns 200 and stores the foreign parent. The same happens for `POST /api/v1/knowledge/{B}/dirs/{dir}/update`.

On the fixed version, step 2 returns an empty `breadcrumbs` list and step 3 returns 404. Directories of B still produce breadcrumbs and can still be used as parents.

## Credits
- 0xMax-Sec (reporter)

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
