[GH-ISSUE #24] XHTTP inbound: unauthenticated session creation enables memory/goroutine exhaustion #5

Open
opened 2026-10-13 21:10:45 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @FrogRocky on GitHub (Aug 17, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amnezia-xray-core/issues/24

Summary

The XHTTP (splithttp) inbound creates a full session for any request that carries a session id in the path/query, without any authentication or rate limiting, enabling unauthenticated memory and goroutine exhaustion.

Affected code: transport/internet/splithttp/hub.go (upsertSession, ~lines 55–93) and transport/internet/splithttp/upload_queue.go:30-38.

Impact

Each accepted request allocates:

  • a session struct + map entry,
  • a channel of GetNormalizedScMaxBufferedPosts() slots (default 30),
  • 2 goroutines,

and sessions live for at least the ~30 s reaper interval even if never used. Session ids are only checked for existence, never validity, and the only pre-session check is a padding length.

Attack scenario (pre-protocol, pre-auth): an attacker sends ~200-byte POSTs like /path/<random-uuid>/0 with a valid-length x_padding header. 1M requests within the reaper window ≈ millions of live goroutines plus heavy allocator pressure → scheduler/memory DoS. With 1 MB bodies (scMaxEachPostBytes default 1,000,000), up to ~30 MB is parked per session for 30 s.

Suggested fix (options)

  • Rate-limit session creation per source address.
  • Allocate session resources lazily — only after the first protocol-valid frame (e.g. after the client proves knowledge of the session key), not on any path-bearing request.
  • Cap concurrent unauthenticated sessions globally and per source.
Originally created by @FrogRocky on GitHub (Aug 17, 2026). Original GitHub issue: https://github.com/amnezia-vpn/amnezia-xray-core/issues/24 ## Summary The XHTTP (splithttp) inbound creates a full session for any request that carries a session id in the path/query, without any authentication or rate limiting, enabling unauthenticated memory and goroutine exhaustion. **Affected code:** `transport/internet/splithttp/hub.go` (`upsertSession`, ~lines 55–93) and `transport/internet/splithttp/upload_queue.go:30-38`. ## Impact Each accepted request allocates: - a session struct + map entry, - a channel of `GetNormalizedScMaxBufferedPosts()` slots (default 30), - 2 goroutines, and sessions live for at least the ~30 s reaper interval even if never used. Session ids are only checked for existence, never validity, and the only pre-session check is a padding length. **Attack scenario (pre-protocol, pre-auth):** an attacker sends ~200-byte POSTs like `/path/<random-uuid>/0` with a valid-length `x_padding` header. 1M requests within the reaper window ≈ millions of live goroutines plus heavy allocator pressure → scheduler/memory DoS. With 1 MB bodies (`scMaxEachPostBytes` default 1,000,000), up to ~30 MB is parked per session for 30 s. ## Suggested fix (options) - Rate-limit session creation per source address. - Allocate session resources lazily — only after the first protocol-valid frame (e.g. after the client proves knowledge of the session key), not on any path-bearing request. - Cap concurrent unauthenticated sessions globally and per source.
Sign in to join this conversation.
No labels
pull-request
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
amnezia-vpn/amnezia-xray-core#5
No description provided.