Cyphrme / Cyphrme/Cyphr

Challenges are issued on a server that can never accept a login

Open
#170 0 comments 0 reactions 0 assignees View on GitHub
bug
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.