A security fix release for v1.13.1. It covers forward-auth identity headers, the WAF "Skip OWASP CRS for path" template, secrets left in the database file after encryption, instance sync, disabled users and WAF event redaction. Some changes need action from operators: check the X-CPM-User and WAF template items, and rotate CA keys and DNS credentials if database backups from before the upgrade exist. The README section Upgrade Notes → Upgrading from v1.13.1 covers every item.
Upgrade notes
Pull and recreate the containers with docker compose pull && docker compose up -d.
These changes also apply when upgrading from an earlier release.
X-CPM-Useris now the sign-in username, or the email address for an account without one. It used to be the display name, which is not unique (users, OAuth providers andADMIN_USERNAMEchoose it), so an upstream trusting it could take one user for another. An upstream that maps users by this header (e.g. Grafana's auth proxy) sees new values and may create new users for them; map the existing ones or key them onX-CPM-User-Id, the account's id. See Identity headers.- WAF template "Skip OWASP CRS for path". The v1.13.x template matched the raw request URI, so
/api/../index.phpor/api/%2e%2e/index.phpturned the OWASP CRS off for a path outside/api/. Replace stored copies (SecRule REQUEST_URI "@beginsWith /api/" … ctl:ruleRemoveByTag=OWASP_CRS") with the new template:SecRule REQUEST_FILENAME "@rx \A/api/(?:[^.]|\.[^.])*\.?\z" "id:9001,phase:1,pass,nolog,ctl:ruleRemoveByTag=OWASP_CRS", which matches the decoded path and skips nothing when it contains... - Deleted secrets are wiped from the database file. SQLite now overwrites deleted content (
PRAGMA secure_delete), and the first start after the upgrade runsVACUUMonce, as does any start whose migrations encrypt or replace stored secrets. Before this, the plaintext CA private keys and DNS provider credentials that earlier releases encrypted on startup, and the CA keys the first sync removed from slaves, could remain in the file's free pages. VACUUM needs free disk space about the size of the database; if it fails, the start logsFailed to VACUUM the databaseand continues. Backups or copies of the database made before the upgrade may still hold them: if any exist, rotate the CA keys and DNS provider credentials. - Forward auth: copy headers
Authorization,Proxy-Authorization,Cookie. When one of them is listed in the copy headers of generic or Authentik forward auth and the auth server returns no value for it, the client's own value is now removed on protected routes, after the auth server has seen it, instead of reaching the upstream. On excluded paths and on API bypass routes the client's credentials still reach the upstream unchanged, since nothing authenticates those requests. - Stored WAF directives left out of the config are now listed on the WAF page. A left-out deny rule (e.g. one using
@ipMatchFromFile) no longer blocks anything, and when aSecDefaultActionis left out, later rules usingblockfollow Coraza's default action instead, which does not block. - Disabled users get no Better Auth session: signing in answers as a wrong password does, and disabling a user now also ends their dashboard sessions.
- Self-registration refuses an email address that another account has or signs in with using Better Auth's "User already exists. Use another email.", whatever the reason. An OAuth sign-up whose email has no
@, or ends in@localhost(the forward-auth portal's names), is refused. - Editing a user's email (dashboard or
PUT /api/v1/users/{id}) stores it trimmed and lowercased, and refuses an address that lowercasing would turn into another one (such as one with the Kelvin sign), as creating a user does. - WAF events also redact credential query parameters in the request URI (
token,api_key,password,code, …), form fields and query parameters with such names in rule messages (ARGS:password), and headers whose names contain such words (e.g.X-Access-Token).