Add middleware and setting for x-ingress-path interpretation

This commit is contained in:
Paul Konstantin Gerke 2023-06-04 15:26:17 +02:00 committed by Christopher Charbonneau Wells
parent 5bc79c2703
commit 1a946a2228
4 changed files with 60 additions and 2 deletions

View File

@ -2,11 +2,12 @@ from os import getenv
from time import time from time import time
import pytz import pytz
from urllib.parse import urlunsplit, urlsplit
from django.conf import settings from django.conf import settings
from django.utils import timezone, translation from django.utils import timezone, translation
from django.contrib.auth.middleware import RemoteUserMiddleware from django.contrib.auth.middleware import RemoteUserMiddleware
from django.http import HttpRequest
class UserLanguageMiddleware: class UserLanguageMiddleware:
""" """
@ -88,3 +89,37 @@ class CustomRemoteUser(RemoteUserMiddleware):
""" """
header = getenv("PROXY_HEADER", "HTTP_REMOTE_USER") header = getenv("PROXY_HEADER", "HTTP_REMOTE_USER")
class HomeAssistant:
def __init__(self, get_response):
self.get_response = get_response
self.use_x_ingress_path_rewrite = settings.HOME_ASSISTANT_USE_X_INGRESS_PATH
def __call__(self, request: HttpRequest):
def wrap_x_ingress_path(org_func):
if request.headers.get("HTTP_X_HASS_SOURCE") != "core.ingress":
return org_func
x_ingress_path = request.headers.get("HTTP_X_INGRESS_PATH")
if x_ingress_path is None:
return org_func
def wrapper(*args, **kwargs):
url = org_func(*args, **kwargs)
url_parts = urlsplit(url)
url = urlunsplit(
url_parts._replace(path=x_ingress_path + url_parts.path)
)
return url
return wrapper
if self.use_x_ingress_path_rewrite:
request.build_absolute_uri = wrap_x_ingress_path(
request.build_absolute_uri
)
return self.get_response(request)

View File

@ -64,6 +64,7 @@ MIDDLEWARE = [
"django.contrib.messages.middleware.MessageMiddleware", "django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware",
"axes.middleware.AxesMiddleware", "axes.middleware.AxesMiddleware",
"babybuddy.middleware.HomeAssistant",
] ]
@ -351,9 +352,13 @@ ROLLING_SESSION_REFRESH = 86400
DEFAULT_AUTO_FIELD = "django.db.models.AutoField" DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
# Baby Buddy configuration # Baby Buddy configuration
# See README.md#configuration for details about these settings. # See https://docs.baby-buddy.net/ for details about these settings.
BABY_BUDDY = { BABY_BUDDY = {
"ALLOW_UPLOADS": bool(strtobool(os.environ.get("ALLOW_UPLOADS") or "True")), "ALLOW_UPLOADS": bool(strtobool(os.environ.get("ALLOW_UPLOADS") or "True")),
"READ_ONLY_GROUP_NAME": "read_only", "READ_ONLY_GROUP_NAME": "read_only",
} }
# Home assistant specific configuration
HOME_ASSISTANT_USE_X_INGRESS_PATH = False

View File

@ -0,0 +1,17 @@
# Home Assistant
## `HOME_ASSISTANT_USE_X_INGRESS_PATH`
*Default:* `False`
This setting should be set to `True` if babybuddy is hosted through the [ingress
service of home assistant](https://developers.home-assistant.io/docs/add-ons/presentation/#ingress).
This setting is necessary so that babybuddy can build correct absolute paths to
itself when run in home assistant. The ingress routing of home assistant
otherwise will obfuscate the true host-url and some functions, like the QR-code
generator for coupling devices might not work correctly.
**Do not enable this feature on other setups.** Attackers might be able to
use this feature to redirect traffic in unexpected ways by manually adding
`X-Ingress-Path` to the request URL.

View File

@ -19,6 +19,7 @@ nav:
- 'configuration/email.md' - 'configuration/email.md'
- 'configuration/security.md' - 'configuration/security.md'
- 'configuration/storage.md' - 'configuration/storage.md'
- 'configuration/homeassistant.md'
- 'User Guide': - 'User Guide':
- 'user-guide/getting-started.md' - 'user-guide/getting-started.md'
- 'user-guide/managing-users.md' - 'user-guide/managing-users.md'