Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Breaking] Samesite Cookie Fix #8269

Merged
merged 4 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion docs/docs/start/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,22 @@ Depending on how your InvenTree installation is configured, you will need to pay
| INVENTREE_USE_X_FORWARDED_HOST | use_x_forwarded_host | Use forwarded host header | `False` |
| INVENTREE_USE_X_FORWARDED_PORT | use_x_forwarded_port | Use forwarded port header | `False` |
| INVENTREE_SESSION_COOKIE_SECURE | cookie.secure | Enforce secure session cookies | `False` |
| INVENTREE_COOKIE_SAMESITE | cookie.samesite | Session cookie mode. Must be one of `Strict | Lax | None`. Refer to the [mozilla developer docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) for more information. | `None` |
| INVENTREE_COOKIE_SAMESITE | cookie.samesite | Session cookie mode. Must be one of `Strict | Lax | None | False`. Refer to the [mozilla developer docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) and the [django documentation]({% include "django.html" %}/ref/settings/#std-setting-SESSION_COOKIE_SAMESITE) for more information. | False |

### Debug Mode

Note that in [debug mode](./intro.md#debug-mode), some of the above settings are automatically adjusted to allow for easier development:

| Setting | Value in Debug Mode | Description |
| --- | --- | --- |
| `INVENTREE_ALLOWED_HOSTS` | `*` | Allow all host in debug mode |
| `CSRF_TRUSTED_ORIGINS` | Value is appended to allow `http://*.localhost:*` | Allow all connections from localhost, for development purposes |
| `INVENTREE_COOKIE_SAMESITE` | `False` | Disable all same-site cookie checks in debug mode |
| `INVENTREE_SESSION_COOKIE_SECURE` | `False` | Disable secure session cookies in debug mode (allow non-https cookies) |

### INVENTREE_COOKIE_SAMESITE vs INVENTREE_SESSION_COOKIE_SECURE

Note that if you set the `INVENTREE_COOKIE_SAMESITE` to `None`, then `INVENTREE_SESSION_COOKIE_SECURE` is automatically set to `True` to ensure that the session cookie is secure! This means that the session cookie will only be sent over secure (https) connections.

### Proxy Settings

Expand Down
28 changes: 23 additions & 5 deletions src/backend/InvenTree/InvenTree/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1093,22 +1093,40 @@
sys.exit(-1)

COOKIE_MODE = (
str(get_setting('INVENTREE_COOKIE_SAMESITE', 'cookie.samesite', 'None'))
str(get_setting('INVENTREE_COOKIE_SAMESITE', 'cookie.samesite', 'False'))
.lower()
.strip()
)

valid_cookie_modes = {'lax': 'Lax', 'strict': 'Strict', 'none': 'None', 'null': 'None'}
# Valid modes (as per the django settings documentation)
valid_cookie_modes = ['lax', 'strict', 'none']

COOKIE_MODE = valid_cookie_modes.get(COOKIE_MODE.lower(), 'None')
if not DEBUG and COOKIE_MODE in valid_cookie_modes:
# Set the cookie mode (in production mode only)
COOKIE_MODE = COOKIE_MODE.capitalize()
else:
# Default to False, as per the Django settings
COOKIE_MODE = False

# Additional CSRF settings
CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN'
CSRF_COOKIE_NAME = 'csrftoken'

CSRF_COOKIE_SAMESITE = COOKIE_MODE
SESSION_COOKIE_SAMESITE = COOKIE_MODE
SESSION_COOKIE_SECURE = get_boolean_setting(
'INVENTREE_SESSION_COOKIE_SECURE', 'cookie.secure', False

"""Set the SESSION_COOKIE_SECURE value based on the following rules:
- False if the server is running in DEBUG mode
- True if samesite cookie setting is set to 'None'
- Otherwise, use the value specified in the configuration file (or env var)
"""
SESSION_COOKIE_SECURE = (
False
if DEBUG
else (
SESSION_COOKIE_SAMESITE == 'None'
or get_boolean_setting('INVENTREE_SESSION_COOKIE_SECURE', 'cookie.secure', True)
)
)

USE_X_FORWARDED_HOST = get_boolean_setting(
Expand Down
2 changes: 1 addition & 1 deletion src/backend/InvenTree/config_template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ use_x_forwarded_port: false
# Cookie settings
cookie:
secure: false
samesite: none
samesite: false

# Cross Origin Resource Sharing (CORS) settings (see https://github.com/adamchainz/django-cors-headers)
cors:
Expand Down
Loading