sec: enforce channel ACL prefixes (presence- + reserved _) - #24
Merged
Conversation
Closes #8. The original handler had two prefix-related gaps: 1. presence-* channels (Pusher protocol convention for authenticated channels with member metadata) were treated as public — anyone with a socket could subscribe to presence-room-1 and read every publish. 2. _-prefixed channels were rejected only on publish. Subscribe ignored the rule, so an attacker could grab a server-reserved name before the server ever uses it. Adds two helpers in handler.go: - channelReserved(name) — true for _-prefixed names. Rejected on both subscribe and publish. - channelRequiresAuth(name) — true for private-* and presence-*. Token verified the same way as the existing private-* path; the token is bound to the channel name in the HMAC, so a private-X token won't let you subscribe to private-Y. The auth-required prefix list is package-level data so adding a new prefix is a one-liner. Tests: - TestSubscribePresenceRequiresAuth: presence-room without token -> AUTH_FAILED. - TestSubscribePresenceValidHMAC: with a token signed for presence-room -> subscribed. - TestSubscribeReservedRejected: _internal -> RESERVED_CHANNEL.
EthanY33
force-pushed
the
sec/channel-acl-prefixes
branch
from
May 7, 2026 23:13
d1b7447 to
4ffdbf4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #8.
The original handler had two prefix-related gaps:
presence-*channels (Pusher's protocol convention for authenticated channels with member metadata) were treated as public. Anyone with a socket could subscribe topresence-room-1and read every publish._*-prefixed channels were rejected only on publish. Subscribe ignored the rule, so an attacker could subscribe to a server-reserved name before the server ever publishes there.This PR replaces the inline
strings.HasPrefixchecks with two named, data-driven helpers:The
authRequiredPrefixesslice is package-level data, so a new prefix is a one-liner.What changed
internal/conn/handler.go:channelReserved/channelRequiresAuthhelpers +authRequiredPrefixesslice.handleSubscribe: reserved -> error; auth required -> verify; otherwise public.handlePublish: samechannelReservedcheck.internal/conn/handler_test.go: 3 new test cases.Test plan
go build ./...clean.go test ./internal/conn/...passes (3 new tests + existing).subscribe channel=presence-roomwithouttokenreturnsAUTH_FAILED.subscribe channel=presence-roomwith a token signed for that channel returnssubscribed.subscribe channel=_internalreturnsRESERVED_CHANNEL.Conflict notes
internal/conn/handler.gooverlaps with PR #20 (channel GC + sub rate limit), PR #17 (channel name length cap), and PR #23 (token jti / replay cache). All overlaps are at distinct lines / additive — small textual rebase whichever lands second.