Document why the client registration override is setup-only #124

Merged
jcoffey-dev merged 1 commits from fix/client-override-recovery-only into main 2026-09-29 17:04:07 +00:00
Owner

Write-up and test for the fix released in 2026.9.29.1 (#123), now rolled to production.

What was wrong: accounts holding oAuthClientOverride, which administrators hold, skipped OAuth client and redirect URI checks. That applied on the sign-in page, at the code exchange and in the device flow, and is upstream's behavior. Client registration (C-5) therefore protected every account except administrators. A link naming a made-up client and an attacker's redirect URI would give an administrator's code, and then a token, to the attacker. The same went for a device code a made-up client asked for and an administrator approved.

The fix (already on main via #123): the permission counts only in bootstrap and recovery mode, where the recovery administrator signs in before any client is registered. Otherwise administrators sign in through a registered client and one of its redirect URIs, like everyone else.

This PR: the C-5 contract text, and tests/e2e/client_override.py: 8 checks, 3 of which failed against a build without the fix, all passing with it. Covers bootstrap, normal mode, the device flow, and recovery. The system integration suite, including OIDC, passes.

Production: checked before release: every node sets INBUXA_ADMIN_URL and INBUXA_WEBMAIL_URL, so both front ends' clients are registered with the redirect URIs they use, and neither relied on the override. After the roll, all nodes run 2026.9.29.1 with no errors, and webmail, admin, JMAP and OAuth metadata answer normally.

Write-up and test for the fix released in **2026.9.29.1** (#123), now rolled to production. **What was wrong:** accounts holding `oAuthClientOverride`, which administrators hold, skipped OAuth client and redirect URI checks. That applied on the sign-in page, at the code exchange and in the device flow, and is upstream's behavior. Client registration (C-5) therefore protected every account except administrators. A link naming a made-up client and an attacker's redirect URI would give an administrator's code, and then a token, to the attacker. The same went for a device code a made-up client asked for and an administrator approved. **The fix (already on main via #123):** the permission counts only in bootstrap and recovery mode, where the recovery administrator signs in before any client is registered. Otherwise administrators sign in through a registered client and one of its redirect URIs, like everyone else. **This PR:** the C-5 contract text, and `tests/e2e/client_override.py`: 8 checks, 3 of which failed against a build without the fix, all passing with it. Covers bootstrap, normal mode, the device flow, and recovery. The system integration suite, including OIDC, passes. **Production:** checked before release: every node sets `INBUXA_ADMIN_URL` and `INBUXA_WEBMAIL_URL`, so both front ends' clients are registered with the redirect URIs they use, and neither relied on the override. After the roll, all nodes run 2026.9.29.1 with no errors, and webmail, admin, JMAP and OAuth metadata answer normally.
jcoffey-dev added 1 commit 2026-09-29 16:46:57 +00:00
Contract and end-to-end check for the client registration override
ci / fork-checks (pull_request) Successful in 47s
ci / build (pull_request) Successful in 4m38s
ad09eeeefb
Documents under C-5 why oAuthClientOverride counts only in bootstrap
and recovery mode, and adds tests/e2e/client_override.py: the
recovery administrator keeps the override in both modes; after setup,
an administrator gets no code for an unregistered client or a
redirect URI its client didn't register, and a device code approved
for an unregistered client can't be exchanged. The script fails
against a build without the change (3 of 8) and passes with it.
jcoffey-dev merged commit 96be849976 into main 2026-09-29 17:04:07 +00:00
jcoffey-dev deleted branch fix/client-override-recovery-only 2026-09-29 17:04:08 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: inbuxa/inbuxa-server#124