mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
resolve findings (#3150)
Fixes all six HIGH findings from the buzz security report, one commit per finding. Independently reviewed to approval by Max at `0158ae542`, plus a deep isolated live pass (clean-room compose stack, weird ports, full product matrix) at the same head — see the buzz-security thread for evidence. `fe65c07c3` merges current `origin/main` on top (new commit, no rebase), inheriting the nostr 0.44.6 bump (#3135) and relay-admin ban gate (#3128). ## Findings and fixes | Finding | Commit | Fix | |---|---|---| | 003 — quinn-proto RUSTSEC-2026-0185 | `e5dcdec72` | Bump quinn-proto 0.11.14 → 0.11.16 (lockfile-only) | | 002/004 — linkify-it quadratic-parse DoS (GHSA-22p9-wv53-3rq4, GHSA-v245-v573-v5vm) | `923b3c20f` | pnpm override `linkify-it: ^5.0.2`; `pnpm why` confirms a single 5.0.2 copy | | 001 — media reads served unauthenticated by default | `0f277e3e2` | Helm `requireMediaGetAuth` defaults to `true` + rendered-chart test pinning the default | | 006 — removed workflow owners retain webhook-exfiltration authority | `4749bd56c` | Fail-closed per-fire authority gate (current owner/admin membership) on **all four** trigger doors (on_event, scheduler pre-claim, manual trigger, webhook — masked as generic 404), save-time gate for `call_webhook` defs, durable disable-on-removal wired to kinds 9001 + 9022 | | 005 — git Smart-HTTP reads ignore channel membership | `e648f2dba` + `0158ae542` | `authorize_git_read`: caller's **current active membership** in the repo's bound channel, checked before any hydration/subprocess on all three read doors (`info_refs` for both services + `upload_pack` POST). Uniform generic 404 denials (no membership probing), no repo-owner bypass, first-`buzz-channel`-tag binding semantics fail closed on ambiguous duplicates (mutation-verified test). Resolution follows the live kind:30617 announcement, so deleted/replaced announcements deny immediately. The committed `e2e-git-perms.sh` guest scenario previously asserted the vulnerability — now asserts denial. | ## Behavior changes to be aware of 1. **Unbound repos fail closed for git reads.** `buzz repos create` emits no `buzz-channel` tag, so CLI-created repos without a binding are unreadable via git HTTP. Correct per finding 005's fail-closed posture; a follow-up could bind CLI-created repos at creation time. 2. **006 is conservative:** a workflow disabled on owner removal does not auto-re-enable if the owner is re-added — explicit re-enable required. 3. Merge conflict resolution in `fe65c07c3`: kept main's `@radix-ui/react-dismissable-layer` 1.1.19 bump alongside the linkify-it security override (`pnpm-workspace.yaml` + lockfile). ## Verification at the merge head `fe65c07c3` (same shell) - buzz-relay `--lib`: 761 passed / 1 failed — the lone red is the known pre-existing `mesh_demo::demo_join_forwarded_arm_round_trips_echo` 504 flake, present on main - SEC-005 module incl. PG behavioral matrix: 8/8 (removed-member, never-member, owner-no-bypass, deleted-30617, malformed/ambiguous binding, owner-mismatch all denied) - buzz-workflow 153/0, buzz-db 84/0; `clippy --all-targets -D warnings` + `fmt --check` clean - Desktop JS 3637/3637, tsc clean, biome clean, file-size/px-text/pubkey-truncation gates clean - `helm lint` + `helm unittest` (40/40) on `deploy/charts/buzz` - All five pre-push hooks green (desktop-check, desktop-test, rust-tests, desktop-tauri-test, branch-skew) Prior review evidence at `0158ae542` (pre-merge): Max's independent exact-head approval + clean-room live regression pass (`WORK_LOGS/2026-07-27_SECURITY_HIGH_LIVE_TEST.md` in his workspace). Max will re-run the deep local pass at this post-merge head before merge. --------- Signed-off-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
This commit is contained in:
co-authored by
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d
Tyler Longwell
parent
a041e2d21e
commit
9b0f744804
@@ -64,7 +64,8 @@
|
||||
{{- end }}
|
||||
{{- if not .Values.relay.requireMediaGetAuth }}
|
||||
⚠ relay.requireMediaGetAuth=false — media GET/HEAD reads are not auth-gated.
|
||||
Keep this false only during staged client rollout.
|
||||
Anyone who learns a media URL/hash can fetch private attachments. Only
|
||||
use for local development or fully public communities.
|
||||
{{- end }}
|
||||
{{- if not .Values.migrate.autoMigrate }}
|
||||
⚠ migrate.autoMigrate=false — relay startup will NOT run sqlx migrations.
|
||||
|
||||
@@ -36,6 +36,34 @@ tests:
|
||||
name: BUZZ_HUDDLE_AUDIO_AVAILABLE
|
||||
value: "true"
|
||||
template: templates/deployment.yaml
|
||||
# Security default: media GET/HEAD reads must be auth-gated out of the
|
||||
# box. A private attachment must never be publicly readable by URL/hash
|
||||
# in an unmodified render. If this assertion fails, someone flipped the
|
||||
# default — treat that as a security regression, not a config tweak.
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: BUZZ_REQUIRE_MEDIA_GET_AUTH
|
||||
value: "true"
|
||||
template: templates/deployment.yaml
|
||||
|
||||
- it: lets an explicit value opt out of media read auth for dev/public deployments
|
||||
set:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
externalRedis.url: redis://h:6379
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
relay.requireMediaGetAuth: false
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: BUZZ_REQUIRE_MEDIA_GET_AUTH
|
||||
value: "false"
|
||||
template: templates/deployment.yaml
|
||||
|
||||
- it: lets an explicit value disable huddle audio in a single-replica render
|
||||
set:
|
||||
|
||||
@@ -107,10 +107,12 @@ relay:
|
||||
sendBuffer: 1000
|
||||
requireAuthToken: true
|
||||
requireRelayMembership: true
|
||||
# Staged rollout gate for authenticated media reads. When true, relay
|
||||
# GET/HEAD /media/* requires Blossom kind 24242 t=get plus relay membership.
|
||||
# Keep false until deployed desktop/mobile/CLI clients attach read auth.
|
||||
requireMediaGetAuth: false
|
||||
# Authenticated media reads: relay GET/HEAD /media/* requires Blossom
|
||||
# kind 24242 t=get plus relay membership. Enabled by default so private
|
||||
# attachments are never publicly readable by URL/hash. Only set false for
|
||||
# local development or fully public communities — desktop, mobile, and CLI
|
||||
# clients all attach read auth.
|
||||
requireMediaGetAuth: true
|
||||
allowNipOaAuth: true
|
||||
pubkeyAllowlist: false
|
||||
corsOrigins: []
|
||||
|
||||
Reference in New Issue
Block a user