Where
AND
-Infinity
0
Severity
5.4
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L

Summary An authenticated user whose features.imagegeneration permission has been revoked can still make the server generate images by sending the feature flag in a chat-completion request. The chat pipeline took the client-supplied features object at face value and never re-checked the permission that the direct image routes enforce, so the denial applied to the UI affordance but not to the server-side generation path.

Preconditions Image generation must be enabled and a provider configured by the administrator (ENABLEIMAGEGENERATION is off by default). The per-user permission defaults to granted, so only deployments where an administrator explicitly revoked it for some users are affected. On 0.10.0 and later the caller must also set params.functioncalling to legacy; on 0.9.x and earlier the legacy mode was the default, so no special parameter was needed. Deployments on native function calling are unaffected, since that path checks the permission before registering the image tools.

Impact A user the administrator has explicitly denied image generation can consume the operator's configured provider through the chat API, spending the operator's API credits and provider quota and writing generated files to the operator's storage. Where an image is present in the conversation and image editing is enabled, the same handler reaches the image-edit provider as well. No provider credentials are exposed, and no other user's data is reachable.

Fix Fixed in 897d69a (#26703). The legacy chat-features block now re-checks features.imagegeneration against the caller's permissions before invoking the image handler, matching the check the direct image routes and the native function-calling path already performed.

Root cause The chat-completions endpoint stored the request's features object into request metadata, and processchatpayload in the chat middleware dispatched to the image handler purely on the truthiness of that client-supplied flag. Permission enforcement lived on the two surfaces that were reached from the UI, the direct /images/generations and /images/edit routes and the native function-calling tool registration, and was simply absent on the legacy chat path. The flag was treated as a statement of user intent, which it is, rather than as an authorization decision, which the handler behind it made it.

Credits @DavidCarliez, for identifying that the chat pipeline honours the client-supplied image-generation feature flag without re-checking the permission.

1 / 2
Source: GitHub
First published (updated )
Severity
4.3
Infoleak
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N

Summary The built-in knowledge search tool returns knowledge bases the calling user has no access to. The tool works out which knowledge bases the caller may read and hands that set to the vector store as a search filter, and that filter is the only access control on the path. Most of the shipped vector backends accept the filter argument on their search method and never apply it, so the search returns matches from every knowledge base in the shared collection. The sibling query method on those same backends does apply a filter, which is why the omission is invisible from the calling code.

Preconditions - The deployment must use one of the affected vector backends, selected with VECTORDB, which defaults to chroma. Chroma applies the filter, so a default deployment is not affected. - Eleven of the fifteen shipped backends ignore the filter: both Qdrant clients, Elasticsearch, OpenSearch, both Milvus clients, openGauss, Oracle 23ai, Pinecone, S3 Vectors and Weaviate. Chroma, pgvector, MariaDB and Valkey apply it and were never affected. - The caller needs a model that can call tools, with the knowledge built-in tools left enabled, which is the default, and with no knowledge attached to the model itself. No elevated role or permission is required. - At least one knowledge base must exist that the caller cannot otherwise read.

Impact A user receives the identifier, name and description of knowledge bases that were never shared with them, and chooses how many results to ask for, so the set can be enumerated by varying the query. The affected collection stores one entry per knowledge base whose text is its name and description, so where those values are themselves sensitive, for example when they name a customer, a project or an investigation, that disclosure is the loss.

The exposure is confined to that metadata. Document text lives in separate per-knowledge-base collections reached by a different call that is scoped by collection rather than by this filter, so stored documents are not returned by this path, and no write access is gained. Because the default backend is unaffected, the population at risk is operators who deliberately moved to an external vector store, which in practice means larger deployments.

Fix Fixed in 0.11.1 by 1d6d4e6e6. Every affected backend now applies the caller-supplied filter in its search method, combined with the collection or tenant scoping that method already performed. Where a backend's filter builder could express only single-value equality it was extended to express set membership, since that is the form the knowledge tool sends, and a filter using any other operator is now rejected rather than dropped. Upgrading is sufficient and no configuration change is required. Deployments on Chroma, pgvector, MariaDB or Valkey were never affected and need no action.

Root cause - The search method of each affected vector client, which declares a filter parameter and never references it. - The built-in knowledge search tool, which relies on that filter as its only access check. - Present from 0.7.0, the release that introduced the tool, through 0.11.0.

Each client exposes a search method and a query method that appear interchangeable from the calling side and differ in whether the caller's filter survives. Search built its request with collection or tenant scoping only, so it was correctly scoped to the collection and entirely unscoped within it. The knowledge tool resolves the caller's readable knowledge bases correctly and passes them down, then reads the results without rechecking them, on the reasonable assumption that a filter handed to a vector store is applied. Because the access decision was delegated wholly to a parameter that most implementations discarded, the caller had no way to observe that it received more than it asked for.

That the same omission repeated across most backends points at the shared interface rather than at any one client: the base class defines the parameter without obliging an implementation to honour it, and each backend was written against the interface independently.

Proof of concept Run against the shipped client classes taken from the 0.11.0 and 0.11.3 release tags, with a real Qdrant engine behind them. Two entries were inserted into the shared knowledge base collection, one readable and one not, mirroring the payload the application writes. The entries were inserted directly rather than created through the application.

On 0.11.0, search given a filter naming only the readable knowledge base returned both, and the same call with no filter returned an identical result set, confirming the filter had no effect:

search(filter={'knowledgebaseid': {'$in': ['kb-allowed']}}) -> ['kb-allowed', 'kb-secret'] search(filter=None) -> ['kb-allowed', 'kb-secret']

On 0.11.3 the same filter returned only the readable entry, while the unfiltered control still returned both, confirming the collection held both and the filter is what excluded the second:

search(filter={'knowledgebaseid': {'$in': ['kb-allowed']}}) -> ['kb-allowed'] search(filter=None) -> ['kb-allowed', 'kb-secret']

The Chroma client, run the same way on both tags, returned only the readable entry in every case, which is the default backend being unaffected. The S3 Vectors client was additionally run against a stub that answers every query with the whole index regardless of the filter it is sent: on 0.11.0 it returned both entries, and on 0.11.3 it returned only the readable one.

The remaining backends were checked by driving each patched filter builder with the exact filter the knowledge tool sends and confirming the request it produces restricts to the readable knowledge base.

Credits Reported by @Classic298.

1 / 2
Source: GitHub
First published (updated )
Severity
6
Infoleak
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary

The channel members endpoint serializes and returns full user models for channel participants, including settings objects. A normal user in a DM can retrieve admin-only sensitive configuration such as webhook URLs and tool server key material (settings.ui.toolServers[].key), which is not available via standard user info APIs.

Details

The endpoint GET /api/v1/channels/{id}/members returns the full serialized user model for every member in the channel. In both the DM and non-DM code paths, the handler constructs the response with [UserModelResponse(user.modeldump(), isactive=...)] and returns it as the users list. Because UserModel (models/users.py) includes a settings object (UserSettings) and arbitrary UI configuration (settings.ui), the endpoint exposes other users' sensitive configuration to any channel participant.

Practically, a regular user who participates in a DM or group can call /api/v1/channels/{id}/members and receive other members' settings, including admin-only details such as webhook notification URLs and tool server configuration, including credential fields like settings.ui.toolServers[].key. These values are not returned by the normal user profile endpoints (e.g., /api/v1/users/{userid}/info).

PoC

1. Start a local Open WebUI instance 2. Log in as admin and in the Admin Panel, go to Settings -> General and check Channels (Beta), then press Save. 3. Create a low-privilege user in the Users tab 4. Click on the admin's profile bottom left, Settings and Integrations. Then click the + after Manage Tool Servers to add some tool server with a secret Bearer token (eg. KEY) 5. Log in as the attacker with the low-privilege account and create a new Direct Message channel with the admin user:

<img width="690" height="383" alt="image" src="https://github.com/user-attachments/assets/70208661-a0db-4457-9984-119056ca3daf" />

7. After creating, open DevTools with F12 and go to the Network tab. Then in the DM UI click on the Users icon top right to see the members. In the network tab, this should have triggered a /api/v1/channels/{id}/members request which responds with the settings key including toolServers and key values:

<img width="1642" height="577" alt="image" src="https://github.com/user-attachments/assets/6639d982-a156-4e8b-861e-587d86d9b152" />

The attacker has now leaked the admin's bearer token for the toolserver they configured.

Impact

Conditions for exploit: channels are enabled and an attacker has a low-privilege account.

Webhook URLs and tool server configurations (including bearer keys) can be exfiltrated from any user.

Original Agent Report

<img width="400" alt="app aikido devai-pentestsprojects116389assessments019d67d4-81c8-7dd2-bb9e-0a4a774b2c78issuessidebarIssue=20440423 (4)" src="https://github.com/user-attachments/assets/8415553a-9f1e-4f73-929c-aa0d18a101ca" />

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203