open-webui/backend/open_webui/utils
Classic298 d11e06f1b7
fix: prevent redirect-based SSRF and enforce collecton write access (#24524)
* fix: prevent redirect-based SSRF in get_image_base64_from_url

Cohort follow-up to PR #24491. That PR patched three call sites
(SafeWebBaseLoader._scrape, get_content_from_url, load_url_image) to
pass allow_redirects=False on the underlying HTTP client; this fourth
call site in utils/files.py was missed.

get_image_base64_from_url() is invoked from convert_url_images_to_base64
in utils/middleware.py on every /api/chat/completions request whose
message content includes an image_url part. validate_url() is called on
the originally-submitted URL only; the aiohttp session.get() call had
no allow_redirects argument and the shared session pool does not
override the aiohttp default (allow_redirects=True). An authenticated
user sending a chat message with image_url pointing at an attacker host
that 302-redirects to 169.254.169.254 / 127.0.0.1 / RFC1918 reached the
internal target. This is the most reachable variant in the redirect
cluster: no special endpoint, no admin permission, no feature flag.

Apply the same one-line fix as the other three call sites: pass
allow_redirects=AIOHTTP_CLIENT_ALLOW_REDIRECTS (defaults to False).

Reported by nayakchinmohan in GHSA-88jq-grjp-jx6f; consolidated under
GHSA-rh5x-h6pp-cjj6.

Co-authored-by: nayakchinmohan <nayakchinmohan@users.noreply.github.com>

* fix: enforce collection write access on process_file endpoint

Cohort follow-up to ba83613ff. That commit added _validate_collection_access
to process_text and process_web (the user-supplied collection_name path)
but missed process_file in the same router.

process_file accepts a user-supplied collection_name and writes the file's
embedded content into that collection via save_docs_to_vector_db. The
file_id is gated by file ownership (line 1562) but collection_name was
unchecked, so an authenticated user could append content from a file they
own into another user's knowledge-base collection by passing the victim's
KB UUID as collection_name. Identical pattern to the process_text and
process_web gaps that ba83613ff closed.

Apply the same one-line gate as the sibling endpoints: when
collection_name is user-supplied (not the default file-{file.id} fallback),
require write access via _validate_collection_access. The shared validator
delegates to filter_accessible_collections, which already correctly
handles file-* prefixes (via has_access_to_file) and KB UUIDs
(via Knowledges.check_access_by_user_id) — admins bypass.

Reported by tenbbughunters (Tenable) in GHSA-4g37-7p2c-38r9 (the
comprehensive write-path filing covering process_text / process_file /
process_web / process_youtube and the _validate_collection_access UUID
root cause), and independently re-identified for the missed process_file
call site by kodareef5 in GHSA-4m74-3cmc-293g.

Co-authored-by: tenbbughunters <tenbbughunters@users.noreply.github.com>
Co-authored-by: kodareef5 <kodareef5@users.noreply.github.com>

* fix: enforce collection write access on process_files_batch endpoint

Cohort follow-up to ba83613ff and the prior process_file fix on this
branch. process_files_batch (line 2604) is the third write endpoint in
the same router that accepts a user-supplied collection_name; it was
covered in the same Tenable filing as process_file and was missed by
the same cohort fix. The endpoint validates per-file ownership at line
2642 but does not check whether the caller has write access to the
target collection_name before save_docs_to_vector_db writes into it
at line 2683-2690 with add=True.

Apply the same one-line gate as the sibling endpoints. Validate only
when collection_name is user-supplied (truthy) so the existing fall
through behavior for the None case is unchanged.

Same Tenable / kodareef5 cohort as the previous commit.

Co-authored-by: tenbbughunters <tenbbughunters@users.noreply.github.com>
Co-authored-by: kodareef5 <kodareef5@users.noreply.github.com>

---------

Co-authored-by: nayakchinmohan <nayakchinmohan@users.noreply.github.com>
Co-authored-by: tenbbughunters <tenbbughunters@users.noreply.github.com>
Co-authored-by: kodareef5 <kodareef5@users.noreply.github.com>
2026-05-11 01:09:15 +09:00
..
access_control chore: format 2026-04-17 14:28:18 +09:00
images refac 2026-04-15 10:17:40 -07:00
mcp refac 2026-04-24 17:04:47 +09:00
telemetry refac 2026-04-24 15:00:47 +09:00
actions.py refac: async db 2026-04-12 14:22:11 -05:00
anthropic.py chore: format 2026-04-14 17:27:31 -05:00
asgi_middleware.py Enhance CommitSessionMiddleware to allow health probes to bypass session management, ensuring faster and more reliable responses. (#24384) 2026-05-09 04:46:00 +09:00
audit.py refac 2026-04-12 16:25:01 -05:00
auth.py chore: format 2026-04-12 18:12:59 -05:00
automations.py refac 2026-05-09 04:17:58 +09:00
calendar.py feat: calendar 2026-04-19 19:15:05 +09:00
channels.py refac 2026-03-17 17:58:01 -05:00
chat.py refac 2026-05-09 04:36:43 +09:00
code_interpreter.py refac 2026-05-09 21:05:49 +09:00
embeddings.py refac: async db 2026-04-12 14:22:11 -05:00
files.py fix: prevent redirect-based SSRF and enforce collecton write access (#24524) 2026-05-11 01:09:15 +09:00
filter.py refac 2026-04-24 18:20:10 +09:00
groups.py refac: async db 2026-04-12 14:22:11 -05:00
headers.py chore: format 2026-05-09 15:25:27 +09:00
logger.py refac 2026-04-10 10:15:55 -07:00
middleware.py refac 2026-05-09 16:06:09 +09:00
misc.py refac 2026-05-09 15:46:33 +09:00
models.py refac 2026-05-09 01:13:16 +09:00
oauth.py refac 2026-05-09 21:05:49 +09:00
payload.py refac 2026-05-09 04:17:58 +09:00
pdf_generator.py refac 2026-03-17 17:58:01 -05:00
plugin.py chore: format 2026-05-09 15:25:27 +09:00
rate_limit.py refac 2026-03-17 17:58:01 -05:00
redis.py refac 2026-04-24 15:21:52 +09:00
response.py refac 2026-04-24 16:31:02 +09:00
sanitize.py refac 2026-03-17 17:58:01 -05:00
security_headers.py refac 2026-04-20 09:10:48 +09:00
session_pool.py refac 2026-04-14 01:17:39 -05:00
task.py refac 2026-05-09 04:17:58 +09:00
tools.py refac 2026-05-09 21:05:49 +09:00
validate.py chore: format 2026-04-12 18:12:59 -05:00
webhook.py refac 2026-04-20 08:34:15 +09:00