Public /events stream exposes issue keys and sync.drift field values to anyone #80

Closed
opened 2026-10-01 16:47:31 +08:00 by Breadway · 1 comment
Owner

How found: while verifying the 2026-10-01 web deploy, curl https://breadboard.breadway.dev/events with no cookie returned HTTP/2 200 and an open stream. Confirmed in crates/breadboard-server/src/http.rs that /events sits outside the authed /api router, and Documentation.md states /healthz and /events are public on purpose.

Confidence: high that it is reachable unauthenticated (observed). Impact is a judgement call, hence low priority and filed as a question.

Explanation: every BoardEvent is broadcast to any subscriber on the internet. Most carry only ids and keys, but sync.drift includes breadboard_value and forgejo_value (the actual field contents, e.g. a title or body), notified includes user ids, and card.created reveals keys of repo-less planning projects (ROAD) that are not visible anywhere else publicly.

Options: require the session cookie or bearer token on /events (EventSource sends cookies with withCredentials: true, which the web client already sets; the bread-emit/breadbar consumers use a token), or strip values from sync.drift and keep the rest public. Update Documentation.md either way.

**How found:** while verifying the 2026-10-01 web deploy, `curl https://breadboard.breadway.dev/events` with no cookie returned `HTTP/2 200` and an open stream. Confirmed in `crates/breadboard-server/src/http.rs` that `/events` sits outside the authed `/api` router, and Documentation.md states `/healthz` and `/events` are public on purpose. **Confidence:** high that it is reachable unauthenticated (observed). Impact is a judgement call, hence low priority and filed as a question. **Explanation:** every `BoardEvent` is broadcast to any subscriber on the internet. Most carry only ids and keys, but `sync.drift` includes `breadboard_value` and `forgejo_value` (the actual field contents, e.g. a title or body), `notified` includes user ids, and `card.created` reveals keys of repo-less planning projects (ROAD) that are not visible anywhere else publicly. **Options:** require the session cookie or bearer token on `/events` (EventSource sends cookies with `withCredentials: true`, which the web client already sets; the bread-emit/breadbar consumers use a token), or strip values from `sync.drift` and keep the rest public. Update Documentation.md either way.
Author
Owner

Implemented in PR #82 at head 5b659de0f7dac7c88fb3fefcda2c81086311b1c1. /events now requires the existing session or bearer authentication. Added coverage for anonymous rejection and both supported client auth methods.

Local verification passed: cargo build --workspace, cargo test --workspace, cargo clippy --workspace --all-targets -- -D warnings, cargo run -p xtask -- check-docs, npm run check -w breadboard-web, and npm run build. CI is pending. Workspace cargo fmt --check reports pre-existing formatting drift in untouched files; changed Rust files were formatted.

Implemented in PR https://git.breadway.dev/Breadway/breadboard/pulls/82 at head `5b659de0f7dac7c88fb3fefcda2c81086311b1c1`. `/events` now requires the existing session or bearer authentication. Added coverage for anonymous rejection and both supported client auth methods. Local verification passed: `cargo build --workspace`, `cargo test --workspace`, `cargo clippy --workspace --all-targets -- -D warnings`, `cargo run -p xtask -- check-docs`, `npm run check -w breadboard-web`, and `npm run build`. CI is pending. Workspace `cargo fmt --check` reports pre-existing formatting drift in untouched files; changed Rust files were formatted.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/breadboard#80
No description provided.