Skip to content

Fix panic when rejecting a headless request#63189

Merged
ravicious merged 10 commits intomasterfrom
r7s/headless-reject
Feb 3, 2026
Merged

Fix panic when rejecting a headless request#63189
ravicious merged 10 commits intomasterfrom
r7s/headless-reject

Conversation

@ravicious
Copy link
Copy Markdown
Member

Closes #58864.

changelog: Fixed a server error when rejecting a headless authentication request in the Web UI

This might have been introduced by #53741 but I haven't checked because I wasn't able to build the binary due to Rust issues.

The cause of the issue appears to be that the client uses the same endpoint when accepting or rejecting a headless request. When rejecting, the MFA response isn't required and the client doesn't send it, but the handler assumed it's always present.

The fix was easy, but I noticed there are no tests that could've catched this regression. I used Claude Code to generate the bulk of them, asking it to look at other tests in lib/web (primarily lib/web/apiserver_test.go). Of course I had to clean them up a fair amount, but it looks like the general pattern does resemble the patterns that can be seen in TestIntegrationsCRUDRolesAnywhere for example (setting up the server and so on).

Comment thread lib/web/headless_test.go Outdated
Comment thread lib/web/headless_test.go Outdated
Comment thread lib/web/headless_test.go Outdated
Comment thread lib/web/headless_test.go Outdated
Comment thread lib/web/headless_test.go
Comment thread lib/web/headless_test.go
Comment thread lib/web/headless_test.go Outdated
@ravicious ravicious requested a review from zmb3 January 28, 2026 14:50
@ravicious ravicious enabled auto-merge February 2, 2026 10:05
Comment thread lib/web/headless.go Outdated
Comment on lines +75 to +77
// MFAResponse is required only when accepting a request.
var mfaResp *proto.MFAAuthenticateResponse
if req.MFAResponse != nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd rather see an if r == nil { return nil, nil } in (*lib/client.MFAChallengeResponse).GetOptionalMFAResponseProtoReq rather than nil checks here and there; there's a lot of callers to GetOptionalMFAResponseProtoReq and I'm not sure how many of them are susceptible to a client not passing the mfa response field (or passing an explicit null).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think that makes sense. I was thinking of this too, but with widely used methods like this one I naturally start to look into introducing the least amount of possible behavior changes, so I ended up doing this in the handler.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Joerger Could you take a look again at the implementation after this change?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new check solves a very similar panic in (*Handler).deleteMFADeviceHandle, FWIW.

@ravicious ravicious added this pull request to the merge queue Feb 2, 2026
@ravicious ravicious removed this pull request from the merge queue due to a manual request Feb 2, 2026
@ravicious ravicious added this pull request to the merge queue Feb 3, 2026
Merged via the queue into master with commit 2607cbe Feb 3, 2026
42 checks passed
@ravicious ravicious deleted the r7s/headless-reject branch February 3, 2026 10:03
@backport-bot-workflows
Copy link
Copy Markdown
Contributor

@ravicious See the table below for backport results.

Branch Result
branch/v17 Create PR
branch/v18 Create PR

mmcallister pushed a commit that referenced this pull request Apr 28, 2026
* Fix panic

* Add tests

* Use `t.Context` instead of `context.Background`

* Remove need for `headlessID` as separate field

* Simplify err asserts when `expectedStatus` is 200

* Update copyright year

* Close `userClient`

* Make `getMFAResponse` a helper

* Remove unnecessary empty lines

* Move nil check to `MFAChallengeResponse`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rejecting a headless auth request generates an odd error

5 participants