Skip to content

TrustedHostMiddleware

Enforces all requests to have a correct set Host header in order to protect against host header attacks. Injects host_is_trusted flag into the scope.

When to use it

Use this middleware when your app is reachable from public networks and you want strict host-header validation.

Typical cases:

  • single-domain deployments;
  • wildcard subdomain deployments;
  • internal/external split where only a subset of hosts is trusted.

Parameters

  • allowed_hosts: iterable of allowed host patterns (supports wildcard like *.example.com).
  • www_redirect: when enabled, redirects to www. host if matching allowed host requires it.
  • block_untrusted_hosts: when True, untrusted hosts get blocked with 400.

Minimal setup

from lilya.apps import Lilya
from lilya.middleware import DefineMiddleware
from lilya.middleware.trustedhost import TrustedHostMiddleware

app = Lilya(
    middleware=[
        DefineMiddleware(
            TrustedHostMiddleware,
            allowed_hosts=["example.com", "*.example.com"],
            www_redirect=True,
        )
    ]
)
from __future__ import annotations

from lilya.apps import Lilya
from lilya.conf.global_settings import Settings
from lilya.middleware import DefineMiddleware
from lilya.middleware.trustedhost import TrustedHostMiddleware

routes = [...]

# Option one
middleware = [
    DefineMiddleware(TrustedHostMiddleware, allowed_hosts=["www.example.com", "*.example.com"])
]

app = Lilya(routes=routes, middleware=middleware)


# Option two - Using the settings module
# Running the application with your custom settings -> LILYA_SETTINGS_MODULE
class AppSettings(Settings):
    @property
    def middleware(self) -> list[DefineMiddleware]:
        return [
            DefineMiddleware(
                TrustedHostMiddleware, allowed_hosts=["www.example.com", "*.example.com"]
            ),
        ]

When an automatic blocking is not wanted, pass block_untrusted_host=False. This way only a flag named host_is_trusted in the scope is set. An use-case is to unlock some special features only for internal host names.

from __future__ import annotations


from lilya.apps import Lilya
from lilya.middleware import DefineMiddleware
from lilya.middleware.trustedhost import TrustedHostMiddleware
from lilya.responses import JSONResponse
from lilya.routing import Path
from lilya.requests import Request


async def example_host_trust_switch(request: Request) -> JSONResponse:
    if request.scope["host_is_trusted"]:
        return JSONResponse({"message": "Welcome home!"})
    else:
        return JSONResponse({"message": "Welcome stranger!"})


routes = [Path("/", handler=example_host_trust_switch)]

middleware = [
    DefineMiddleware(TrustedHostMiddleware, allowed_hosts=["www.example.com", "*.example.com", "example.intern"]),
    DefineMiddleware(TrustedHostMiddleware, allowed_hosts=["example.intern"], block_untrusted_hosts=False)
]

app = Lilya(routes=routes, middleware=middleware)

See also