From 402f5fa1423a2b7a8a79c6cd0cf20ca913c56837 Mon Sep 17 00:00:00 2001 From: Blake Blackshear Date: Sat, 18 May 2024 14:53:49 -0500 Subject: [PATCH] add setting for secure flag on cookie (#11422) * add setting for secure flag on cookie * docs fix --- docs/docs/configuration/authentication.md | 4 ++-- docs/docs/configuration/reference.md | 3 +++ frigate/api/auth.py | 16 ++++++++++++---- frigate/config.py | 1 + 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/docs/docs/configuration/authentication.md b/docs/docs/configuration/authentication.md index ae7230c84..168959bee 100644 --- a/docs/docs/configuration/authentication.md +++ b/docs/docs/configuration/authentication.md @@ -18,11 +18,11 @@ Frigate supports two modes for authentication Frigate stores user information in its database. Password hashes are generated using industry standard PBKDF2-SHA256 with 600,000 iterations. Upon successful login, a JWT token is issued with an expiration date and set as a cookie. The cookie is refreshed as needed automatically. This JWT token can also be passed in the Authorization header as a bearer token. -Users are managed in the UI under Settings > Authentication. +Users are managed in the UI under Settings > Users. #### Onboarding -On startup, an admin user and password are generated and printed in the logs. It is recommended to set a new password for the admin account after logging in for the first time under Settings > Authentication. +On startup, an admin user and password are generated and printed in the logs. It is recommended to set a new password for the admin account after logging in for the first time under Settings > Users. #### Resetting admin password diff --git a/docs/docs/configuration/reference.md b/docs/docs/configuration/reference.md index 7bbbfe5d3..658e6488d 100644 --- a/docs/docs/configuration/reference.md +++ b/docs/docs/configuration/reference.md @@ -73,6 +73,9 @@ auth: reset_admin_password: False # Optional: Cookie to store the JWT token for native auth (default: shown below) cookie_name: frigate_token + # Optional: Set secure flag on cookie. (default: shown below) + # NOTE: This should be set to True if you are using TLS + cookie_secure: False # Optional: Session length in seconds (default: shown below) session_length: 86400 # 24 hours # Optional: Refresh time in seconds (default: shown below) diff --git a/frigate/api/auth.py b/frigate/api/auth.py index 93d618376..ff1fa6bff 100644 --- a/frigate/api/auth.py +++ b/frigate/api/auth.py @@ -160,10 +160,10 @@ def create_encoded_jwt(user, expiration, secret): return jwt.encode({"alg": "HS256"}, {"sub": user, "exp": expiration}, secret) -def set_jwt_cookie(response, cookie_name, encoded_jwt, expiration): +def set_jwt_cookie(response, cookie_name, encoded_jwt, expiration, secure): # TODO: ideally this would set secure as well, but that requires TLS response.set_cookie( - cookie_name, encoded_jwt, httponly=True, expires=expiration, secure=False + cookie_name, encoded_jwt, httponly=True, expires=expiration, secure=secure ) @@ -196,6 +196,7 @@ def auth(): fail_response.headers["location"] = "/login" JWT_COOKIE_NAME = current_app.frigate_config.auth.cookie_name + JWT_COOKIE_SECURE = current_app.frigate_config.auth.cookie_secure JWT_REFRESH = current_app.frigate_config.auth.refresh_time JWT_SESSION_LENGTH = current_app.frigate_config.auth.session_length @@ -256,7 +257,11 @@ def auth(): user, new_expiration, current_app.jwt_token ) set_jwt_cookie( - success_response, JWT_COOKIE_NAME, new_encoded_jwt, new_expiration + success_response, + JWT_COOKIE_NAME, + new_encoded_jwt, + new_expiration, + JWT_COOKIE_SECURE, ) success_response.headers["remote-user"] = user @@ -284,6 +289,7 @@ def logout(): @limiter.limit(get_rate_limit, deduct_when=lambda response: response.status_code == 400) def login(): JWT_COOKIE_NAME = current_app.frigate_config.auth.cookie_name + JWT_COOKIE_SECURE = current_app.frigate_config.auth.cookie_secure JWT_SESSION_LENGTH = current_app.frigate_config.auth.session_length content = request.get_json() user = content["user"] @@ -299,7 +305,9 @@ def login(): expiration = int(time.time()) + JWT_SESSION_LENGTH encoded_jwt = create_encoded_jwt(user, expiration, current_app.jwt_token) response = make_response({}, 200) - set_jwt_cookie(response, JWT_COOKIE_NAME, encoded_jwt, expiration) + set_jwt_cookie( + response, JWT_COOKIE_NAME, encoded_jwt, expiration, JWT_COOKIE_SECURE + ) return response return make_response({"message": "Login failed"}, 400) diff --git a/frigate/config.py b/frigate/config.py index e8c850bef..c2711aa0e 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -135,6 +135,7 @@ class AuthConfig(FrigateBaseModel): cookie_name: str = Field( default="frigate_token", title="Name for jwt token cookie", pattern=r"^[a-z]_*$" ) + cookie_secure: bool = Field(default=False, title="Set secure flag on cookie") session_length: int = Field( default=86400, title="Session length for jwt session tokens", ge=60 )