d67f3d9 Start by renaming variables to something more generic. This will give us a bit more flexibility as we look to other session management mechanisms.
03a7e35 Default docker installations should generate a random key instead of using a static secret that everyone can see.
2c1dacb We should verify signatures to make the whole session secret meaningful.
8c37edd Even though "User.email" is enforced as unique at signup, it is not a unique field in the database. Let's use "User.id" instead. This also makes it more difficult to do a session stealing attack.
This PR changes a few things around how sessions are handled in order to improve security.
Problem 1: The session secret is hard-coded. Few people will provide their own thus the security of the whole project is a risk for everyone who deploys it.
Solution: One first run, the start script generates a randomly generated session key and stores it to a file. If no secret key is provided, the start script will grab this one. WEBUI_JWT_SECRET_KEY is still accepted. I flagged the line in config.py to be deprecated in the next major release.
Problem 2: JWT signatures were not verified. This makes session stealing easy.
Solution: Remove the option turning off jwt signature verification.
Problem 3: JWTs use email address as the primary method to identify a user. This makes step 2 involve no guesswork at all. If you know someone has session, you can just build the correctly formed JWT and BE them.
Solution: Use database user ids in the JWT instead.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/open-webui/open-webui/pull/624
**Author:** [@explorigin](https://github.com/explorigin)
**Created:** 2/2/2024
**Status:** ✅ Merged
**Merged:** 2/4/2024
**Merged by:** [@tjbck](https://github.com/tjbck)
**Base:** `main` ← **Head:** `session-security`
---
### 📝 Commits (10+)
- [`d67f3d9`](https://github.com/open-webui/open-webui/commit/d67f3d982b3548cabb5f3fbf379927f596c03976) Start by renaming variables to something more generic. This will give us a bit more flexibility as we look to other session management mechanisms.
- [`03a7e35`](https://github.com/open-webui/open-webui/commit/03a7e35967dde9f75f2cc3e752ecb74c887feae5) Default docker installations should generate a random key instead of using a static secret that everyone can see.
- [`2c1dacb`](https://github.com/open-webui/open-webui/commit/2c1dacb9b67b35840da8f812d6ddc0deb74d712d) We should verify signatures to make the whole session secret meaningful.
- [`8c37edd`](https://github.com/open-webui/open-webui/commit/8c37edd027b52426ffdaf715da7cbbe613b4df8e) Even though "User.email" is enforced as unique at signup, it is not a unique field in the database. Let's use "User.id" instead. This also makes it more difficult to do a session stealing attack.
- [`e15dbdc`](https://github.com/open-webui/open-webui/commit/e15dbdc46ac82960e88e99f0225a5197dd9bff78) Pass the instance we're using.
- [`4fceb40`](https://github.com/open-webui/open-webui/commit/4fceb404bdbc8e250360a16b4108058af8aa50e0) Call `jwt.decode` with the expected algorithms
- [`44799e2`](https://github.com/open-webui/open-webui/commit/44799e2018274acc1467d74360efff0288818721) Remove some extraneous imports
- [`e2d481d`](https://github.com/open-webui/open-webui/commit/e2d481d99a7009a71dd27f132ada7d18e5f72037) Move the random secret generation to start.sh.
- [`1031638`](https://github.com/open-webui/open-webui/commit/1031638d8296fdd6b8a7e6e5d6495a5f8d111f8c) Maintain backward compatibility with WEBUI_JWT_SECRET_KEY for the time being
- [`8298cef`](https://github.com/open-webui/open-webui/commit/8298cefd62cad4b66b2225852547b5b58f32c0a5) Fix bash condition formatting
### 📊 Changes
**8 files changed** (+34 additions, -23 deletions)
<details>
<summary>View changed files</summary>
📝 `Dockerfile` (+1 -1)
📝 `backend/apps/web/models/auths.py` (+1 -6)
📝 `backend/apps/web/routers/auths.py` (+2 -2)
📝 `backend/apps/web/routers/chats.py` (+0 -3)
📝 `backend/config.py` (+6 -3)
📝 `backend/start.sh` (+16 -1)
📝 `backend/utils/utils.py` (+7 -7)
📝 `docker-compose.yaml` (+1 -0)
</details>
### 📄 Description
This PR changes a few things around how sessions are handled in order to improve security.
Problem 1: The session secret is hard-coded. Few people will provide their own thus the security of the whole project is a risk for everyone who deploys it.
Solution: One first run, the start script generates a randomly generated session key and stores it to a file. If no secret key is provided, the start script will grab this one. WEBUI_JWT_SECRET_KEY is still accepted. I flagged the line in config.py to be deprecated in the next major release.
Problem 2: JWT signatures were not verified. This makes session stealing easy.
Solution: Remove the option turning off jwt signature verification.
Problem 3: JWTs use email address as the primary method to identify a user. This makes step 2 involve no guesswork at all. If you know someone has session, you can just build the correctly formed JWT and BE them.
Solution: Use database user ids in the JWT instead.
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/624
Author: @explorigin
Created: 2/2/2024
Status: ✅ Merged
Merged: 2/4/2024
Merged by: @tjbck
Base:
main← Head:session-security📝 Commits (10+)
d67f3d9Start by renaming variables to something more generic. This will give us a bit more flexibility as we look to other session management mechanisms.03a7e35Default docker installations should generate a random key instead of using a static secret that everyone can see.2c1dacbWe should verify signatures to make the whole session secret meaningful.8c37eddEven though "User.email" is enforced as unique at signup, it is not a unique field in the database. Let's use "User.id" instead. This also makes it more difficult to do a session stealing attack.e15dbdcPass the instance we're using.4fceb40Calljwt.decodewith the expected algorithms44799e2Remove some extraneous importse2d481dMove the random secret generation to start.sh.1031638Maintain backward compatibility with WEBUI_JWT_SECRET_KEY for the time being8298cefFix bash condition formatting📊 Changes
8 files changed (+34 additions, -23 deletions)
View changed files
📝
Dockerfile(+1 -1)📝
backend/apps/web/models/auths.py(+1 -6)📝
backend/apps/web/routers/auths.py(+2 -2)📝
backend/apps/web/routers/chats.py(+0 -3)📝
backend/config.py(+6 -3)📝
backend/start.sh(+16 -1)📝
backend/utils/utils.py(+7 -7)📝
docker-compose.yaml(+1 -0)📄 Description
This PR changes a few things around how sessions are handled in order to improve security.
Problem 1: The session secret is hard-coded. Few people will provide their own thus the security of the whole project is a risk for everyone who deploys it.
Solution: One first run, the start script generates a randomly generated session key and stores it to a file. If no secret key is provided, the start script will grab this one. WEBUI_JWT_SECRET_KEY is still accepted. I flagged the line in config.py to be deprecated in the next major release.
Problem 2: JWT signatures were not verified. This makes session stealing easy.
Solution: Remove the option turning off jwt signature verification.
Problem 3: JWTs use email address as the primary method to identify a user. This makes step 2 involve no guesswork at all. If you know someone has session, you can just build the correctly formed JWT and BE them.
Solution: Use database user ids in the JWT instead.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.