TrustedReferrerMiddleware¶
Check if the sent referrer is same-origin
or matches trusted referrer hosts.
In contrast to the TrustedHostMiddleware by default nothing is enforced and only a flag (referrer_is_trusted
) is set in the scope.
You can change this by providing block_untrusted_referrers=True
.
When used for an API it is recommended to add ""
to allowed_referrers
. This evaluates requests
without a set referrer header as valid.
from __future__ import annotations
from lilya.apps import Lilya
from lilya.middleware import DefineMiddleware
from lilya.middleware.trustedreferrer import TrustedReferrerMiddleware
from lilya.routing import Include, Path
from lilya.requests import Request
from lilya.responses import Response
async def safe_get_search(request: Request) -> Response:
search_param = ""
if request.scope["referrer_is_trusted"]:
search_param = request.query_params["q"]
return Response(f"Search for {search_param}.")
routes = [Path("/", handler=safe_get_search)]
app = Lilya(routes=routes, middleware=[
DefineMiddleware(TrustedReferrerMiddleware, allowed_referrers=["example.com"])
])
Let's go fancy and block also invalid referred request or requests not originating from web browsers
from __future__ import annotations
from lilya.apps import Lilya
from lilya.middleware import DefineMiddleware
from lilya.middleware.trustedreferrer import TrustedReferrerMiddleware
from lilya.routing import Include
routes = [
Include("/api", routes=[], middleware=[
# allow non-referred requests (non-user) or as referrer example.com, external.example.com
DefineMiddleware(TrustedReferrerMiddleware, block_untrusted_referrers=True, allowed_referrers=["", "example.com", "external.example.com"]),
# mark referals from "external.example.com" as trusted, disable same origin logic
# You can check now `referrer_is_trusted` in the scope.
DefineMiddleware(TrustedReferrerMiddleware, allow_same_origin=False, allowed_referrers=["external.example.com"])
]),
Include("/settings", routes=[], middleware=[
# only allow access from example. Exclude non-webrowsers which doesn't send a referrer header
DefineMiddleware(TrustedReferrerMiddleware, allow_same_origin=False, block_untrusted_referrers=True, allowed_referrers=["example.com"]),
]),
# mark referals from "example.com" and the same origin as trusted
# Import e.g. data for a search
Include("/", routes=[], middleware=[
DefineMiddleware(TrustedReferrerMiddleware, allowed_referrers=["example.com"])
])
]
app = Lilya(routes=routes)