This commit is contained in:
Timothy Jaeryang Baek
2026-02-11 16:16:41 -06:00
parent 5c1c9a4dcb
commit 773787c74c
3 changed files with 60 additions and 2 deletions
+9 -1
View File
@@ -5,7 +5,8 @@ from typing import Optional
from sqlalchemy.orm import Session
from open_webui.internal.db import Base, JSONField, get_db, get_db_context
from open_webui.models.users import User, UserModel, UserProfileImageResponse, Users
from pydantic import BaseModel
from open_webui.utils.validate import validate_profile_image_url
from pydantic import BaseModel, field_validator
from sqlalchemy import Boolean, Column, String, Text
log = logging.getLogger(__name__)
@@ -74,6 +75,13 @@ class SignupForm(BaseModel):
password: str
profile_image_url: Optional[str] = "/user.png"
@field_validator("profile_image_url")
@classmethod
def check_profile_image_url(cls, v: Optional[str]) -> Optional[str]:
if v is not None:
return validate_profile_image_url(v)
return v
class AddUserForm(SignupForm):
role: Optional[str] = "pending"
+12 -1
View File
@@ -12,9 +12,10 @@ from open_webui.models.groups import Groups, GroupMember
from open_webui.models.channels import ChannelMember
from open_webui.utils.misc import throttle
from open_webui.utils.validate import validate_profile_image_url
from pydantic import BaseModel, ConfigDict
from pydantic import BaseModel, ConfigDict, field_validator
from sqlalchemy import (
BigInteger,
JSON,
@@ -154,6 +155,11 @@ class UpdateProfileForm(BaseModel):
gender: Optional[str] = None
date_of_birth: Optional[datetime.date] = None
@field_validator("profile_image_url")
@classmethod
def check_profile_image_url(cls, v: str) -> str:
return validate_profile_image_url(v)
class UserGroupIdsModel(UserModel):
group_ids: list[str] = []
@@ -237,6 +243,11 @@ class UserUpdateForm(BaseModel):
profile_image_url: str
password: Optional[str] = None
@field_validator("profile_image_url")
@classmethod
def check_profile_image_url(cls, v: str) -> str:
return validate_profile_image_url(v)
class UsersTable:
def insert_new_user(
+39
View File
@@ -0,0 +1,39 @@
"""Validation utilities for user-supplied input."""
# Known static asset paths used as default profile images
_ALLOWED_STATIC_PATHS = (
"/user.png",
"/static/favicon.png",
)
def validate_profile_image_url(url: str) -> str:
"""
Pydantic-compatible validator for profile image URLs.
Allowed formats:
- Empty string (falls back to default avatar)
- data:image/* URIs (base64-encoded uploads from the frontend)
- Known static asset paths (/user.png, /static/favicon.png)
Returns the url unchanged if valid, raises ValueError otherwise.
"""
if not url:
return url
_ALLOWED_DATA_PREFIXES = (
"data:image/png",
"data:image/jpeg",
"data:image/gif",
"data:image/webp",
)
if any(url.startswith(prefix) for prefix in _ALLOWED_DATA_PREFIXES):
return url
if url in _ALLOWED_STATIC_PATHS:
return url
raise ValueError(
"Invalid profile image URL: only data URIs and default avatars are allowed."
)