mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-08 03:08:02 +00:00
fix: harden profile image URL validation per review feedback
- Restrict data URIs to safe raster formats (png/jpeg/gif/webp); SVG is excluded because it can carry embedded scripts. - Block scheme-relative URLs (//host/path) which browsers resolve against the current protocol, bypassing the relative-path check.
This commit is contained in:
parent
9af9635751
commit
a3a385c4d9
1 changed files with 18 additions and 5 deletions
|
|
@ -1,5 +1,14 @@
|
|||
"""Validation utilities for user-supplied input."""
|
||||
|
||||
# Raster image formats safe to accept as base64 data URIs.
|
||||
# SVG is intentionally excluded: it can carry embedded scripts.
|
||||
_SAFE_DATA_IMAGE_PREFIXES = (
|
||||
'data:image/png',
|
||||
'data:image/jpeg',
|
||||
'data:image/gif',
|
||||
'data:image/webp',
|
||||
)
|
||||
|
||||
|
||||
def validate_profile_image_url(url: str) -> str:
|
||||
"""
|
||||
|
|
@ -9,27 +18,31 @@ def validate_profile_image_url(url: str) -> str:
|
|||
- Empty string (falls back to default avatar)
|
||||
- Relative paths starting with ``/`` (internal assets and API routes)
|
||||
- ``http://`` and ``https://`` URLs (external avatars, OAuth pictures)
|
||||
- ``data:image/*`` URIs (base64-encoded uploads from the frontend)
|
||||
- ``data:image/{png,jpeg,gif,webp}`` URIs (base64-encoded uploads)
|
||||
|
||||
All other schemes (javascript:, file:, ftp:, etc.) are rejected.
|
||||
SVG data URIs are rejected because SVG can contain embedded scripts.
|
||||
"""
|
||||
if not url:
|
||||
return url
|
||||
|
||||
# Relative paths: covers /user.png, /static/favicon.png,
|
||||
# /api/v1/users/{id}/profile/image, and any future internal routes.
|
||||
if url.startswith('/'):
|
||||
# Exclude scheme-relative URLs (//host/path) which browsers resolve
|
||||
# against the current protocol.
|
||||
if url.startswith('/') and not url.startswith('//'):
|
||||
return url
|
||||
|
||||
# External images served over HTTP(S), e.g. OAuth provider avatars.
|
||||
if url.startswith('https://') or url.startswith('http://'):
|
||||
return url
|
||||
|
||||
# Base64-encoded images uploaded via the frontend.
|
||||
if url.startswith('data:image/'):
|
||||
# Base64-encoded raster images uploaded via the frontend.
|
||||
if any(url.startswith(prefix) for prefix in _SAFE_DATA_IMAGE_PREFIXES):
|
||||
return url
|
||||
|
||||
raise ValueError(
|
||||
'Invalid profile image URL: must be a relative path, an HTTP(S) URL, '
|
||||
'or a data:image URI.'
|
||||
'or a data:image URI (png/jpeg/gif/webp).'
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue