mirror of
https://github.com/open-webui/open-webui.git
synced 2026-05-18 05:05:09 +02:00
* fix: prevent mass-assignment user_id spoofing in POST /api/v1/evaluations/feedback Two independent gaps in backend/open_webui/models/feedbacks.py let an authenticated caller forge the `user_id` (and `id`, `version`) on a new feedback record submitted to POST /api/v1/evaluations/feedback: 1. `FeedbackForm` declared `model_config = ConfigDict(extra='allow')`, so Pydantic preserved any extra fields supplied in the request body — including `user_id`, `id`, `version`. The form is the public input boundary for the endpoint and should not accept unknown fields. 2. In `insert_new_feedback`, the dict literal placed `**form_data.model_dump()` AFTER `'id': id`, `'user_id': user_id`, `'version': 0`. Python dict-literal duplicate-key resolution is last-wins, so any of those fields present in `form_data` overwrote the server-derived values. Combined effect: a regular user could POST a feedback record with an arbitrary `user_id`, attributing the rating to any other user. The Elo leaderboard at backend/open_webui/routers/evaluations.py computes model rankings from these records, and the admin export (GET /api/v1/evaluations/feedbacks/export) and admin list (GET /api/v1/evaluations/feedbacks/all) display the spoofed attribution. Two fixes, defense-in-depth: - FeedbackForm: switch `extra='allow'` to `extra='ignore'` so Pydantic drops unknown fields at parse time. Sub-models (RatingData / MetaData / SnapshotData) intentionally keep `extra='allow'` because their contents are deliberately schema-flexible — the spoofing surface was the form, not the sub-payloads. - insert_new_feedback: spread `form_data.model_dump()` first, then overlay server-controlled fields (`id`, `user_id`, `version`, `created_at`, `updated_at`) so the explicit keys win on duplicate-key resolution regardless of what reaches the function. Matches the secure pattern already used in backend/open_webui/models/functions.py:120. Reported by yantongggg in GHSA-rjmp-vjf2-qf4g. Same root-cause class as the prior published GHSA-hr43-rjmr-7wmm (folder mass-assignment, fixed in v0.9.0); that fix did not generalize across the codebase, this fix closes the feedback variant. Co-authored-by: yantongggg <yantongggg@users.noreply.github.com> * chore: trim comments --------- Co-authored-by: yantongggg <yantongggg@users.noreply.github.com>