Challenges are issued on a server that can never accept a login
- Dominant language
- Rust
- Stars
- 3
- Forks
- 0
- Avg merge
- 1d 42m
- Merged PRs (30d)
- 11
Description
A server configured with a signing key but no audience issues login challenges that succeed, for logins that can never succeed. The challenge handler guards against one version of this trap and not the other.
## Reproduction
Run a server with a signing key and no `--audience`:
```
cyphr-server serve --signing-key-path ./signing-key.json --data-dir ./data
```
```
POST /auth/challenge
-> HTTP 200
{"v":1,"payload":{"challenge":"WRxCcxkpQYMEWPOimcKM8YQiMem-W90UlnfqbvlsxdU"},
"statement":{"kind":"unsigned"}}
POST /auth/login (any body)
-> HTTP 500
{"v":1,"payload":{"error":"server is not configured to accept logins", ...},
"statement":{"kind":"unsigned"}}
```
## Why it matters
The `challenge` handler in `rs/cyphr-server/src/auth/login.rs` guards only on there being no configured identity, and its own doc comment states the principle the guard exists to serve:
> A keyless server (no configured signing identity) never issues a challenge at all: a nonce that can never be redeemed by a login that can never succeed is a silent trap, not a service worth offering, so this fails the same honest way `login` does rather than succeeding here and only failing later.
The unset-audience case is that same silent trap, and the guard does not reach it. The keyless case is handled honestly — both routes refuse with a 501 and a message pointing at `GET /server`. The audience case succeeds at the challenge and fails at the login.
An integrator meeting this sees challenges working and logins returning a 500, which reads as a server fault rather than as a missing setting on their own deployment.
Secondary: an unset audience is deployment misconfiguration, and the login handler reports it as an internal error with a 500. Every other configuration-shaped refusal on this surface is a 501 with an explanatory message.
## Two cheap fixes
Extend the `challenge` guard to cover a missing audience and share the keyless rejection's honest 501 shape. Or refuse the configuration at startup: a server holding a signing key but no audience offers half a login surface either way, and failing at boot is the earliest place a deployer can be told.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the signing-key-without-audience commands, then read rs/cyphr-server/src/auth/login.rs, especially the challenge and login handlers and the existing keyless rejection. The work is done when this configuration no longer offers a challenge that cannot be redeemed, and the refusal is reported consistently as configuration guidance rather than an internal server error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- authentication, backend-api-design
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100