PASS over 72 bytes gets HTTP 500, and the IRC listener confirms a password it did not store #144

Closed
opened 2026-10-20 16:51:33 +02:00 by clawbot · 0 comments
Collaborator

bcrypt hashes at most 72 bytes, and golang.org/x/crypto/bcrypt returns an error for a longer password. SetPassword (internal/db/auth.go) passes that error up, and nothing before it checks the length. Seen on eceb5f2:

  • Over the HTTP API, PASS with an 80-byte password gets 500 {"error":"internal error"} from handlePass (internal/handlers/auth.go), with set password failed: hash password: bcrypt: password length exceeds 72 bytes in the log. README.md reserves 500 for server-side failures and says only that a password must be at least 8 characters.
  • Over the IRC listener, PASS with an 80-byte password after registration gets NOTICE pwirc :Password set. You can reconnect using PASS <password> with your nick., because setPassword (internal/ircserver/conn.go) logs the error and returns nothing, and handlePassPostReg (internal/ircserver/commands.go) sends the notice regardless. Nothing was stored: POST /api/v1/login with that password gets 401. A PASS before registration (completeRegistration in internal/ircserver/conn.go) fails the same way, silently.

Fix: refuse a password over 72 bytes before hashing, on both transports, with the reply the too-short case already uses (461 over the HTTP API, the NOTICE over the IRC listener), and send the IRC "Password set" notice only when SetPassword succeeded, which means setPassword has to return its error. A PASS before registration that is refused for length should get the same notice once registration completes; today a too-short one is dropped silently, so treat both the same. README.md PASS and the IRC listener's registration paragraph say 8 to 72 bytes.

Definition of done

  1. PASS with a password over 72 bytes gets the same kind of reply as one under 8 on both transports, and no 500.
  2. The IRC listener confirms a password only after it is stored, and a pre-registration PASS that was refused is reported after registration.
  3. Tests in internal/handlers and internal/ircserver for both.
  4. README.md gives the range.
  5. One reviewed PR against next.

Model: fable-5-1

bcrypt hashes at most 72 bytes, and `golang.org/x/crypto/bcrypt` returns an error for a longer password. `SetPassword` (`internal/db/auth.go`) passes that error up, and nothing before it checks the length. Seen on `eceb5f2`: - Over the HTTP API, `PASS` with an 80-byte password gets `500` `{"error":"internal error"}` from `handlePass` (`internal/handlers/auth.go`), with `set password failed: hash password: bcrypt: password length exceeds 72 bytes` in the log. `README.md` reserves 500 for server-side failures and says only that a password must be at least 8 characters. - Over the IRC listener, `PASS` with an 80-byte password after registration gets `NOTICE pwirc :Password set. You can reconnect using PASS <password> with your nick.`, because `setPassword` (`internal/ircserver/conn.go`) logs the error and returns nothing, and `handlePassPostReg` (`internal/ircserver/commands.go`) sends the notice regardless. Nothing was stored: `POST /api/v1/login` with that password gets 401. A `PASS` before registration (`completeRegistration` in `internal/ircserver/conn.go`) fails the same way, silently. Fix: refuse a password over 72 bytes before hashing, on both transports, with the reply the too-short case already uses (461 over the HTTP API, the NOTICE over the IRC listener), and send the IRC "Password set" notice only when `SetPassword` succeeded, which means `setPassword` has to return its error. A `PASS` before registration that is refused for length should get the same notice once registration completes; today a too-short one is dropped silently, so treat both the same. `README.md` PASS and the IRC listener's registration paragraph say 8 to 72 bytes. ## Definition of done 1. `PASS` with a password over 72 bytes gets the same kind of reply as one under 8 on both transports, and no 500. 2. The IRC listener confirms a password only after it is stored, and a pre-registration `PASS` that was refused is reported after registration. 3. Tests in `internal/handlers` and `internal/ircserver` for both. 4. `README.md` gives the range. 5. One reviewed PR against `next`. Model: fable-5-1
clawbot self-assigned this 2026-10-20 16:51:33 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/neoirc#144