Security¶
The viewer has no authentication of its own
Anything recorded is visible to anyone who can reach the mount path. That includes full URLs with query strings, request and response headers, SQL statements and their bound parameters.
Do not expose it on the public internet.
Options, in rough order of preference¶
Do not install it in production¶
The simplest control. Gate it on an environment variable:
Put it behind an admin you already authenticate¶
If you run SQLAdmin, register the profiler as a view inside it. Every route then goes through SQLAdmin's authentication backend, and there is nothing new to secure:
from asgi_profiler.contrib.sqladmin import register
profiler = install(app, mount_path=None)
register(admin, profiler)
Guard it yourself¶
authorize is called for every viewer request. Return False to deny:
It may be async:
Async guards used to fail open
A coroutine object is truthy, so an early version of this let every
request through when authorize was async. It is awaited now, and there
is a regression test for both directions — but if you are pinned below
0.1.0, check.
Network-level¶
Bind it somewhere only your VPN or an SSH tunnel can reach.
What is stored¶
- Headers listed in
redacted_headersare stored as<redacted>—authorization,cookie,x-api-keyand friends. Setcapture_headers=Falseto store no headers at all. - Query strings are stored in full. A token in a URL will be recorded.
- Bound parameters are stored, truncated at 500 characters. Personal data
in a
WHEREclause ends up in the capture. - Request and response bodies are never read, and so are never stored.
If a SQLiteStorage capture leaves the machine, treat the file as containing
whatever your queries contain.