mirror of
https://github.com/amnezia-vpn/amnezia-xray-core.git
synced 2026-10-13 21:33:49 +00:00
[GH-ISSUE #25] Shadowsocks: replay protection is disabled (IV/nonce dedup never runs) #4
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
amnezia-vpn/amnezia-xray-core#4
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @FrogRocky on GitHub (Aug 17, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amnezia-xray-core/issues/25
Summary
Shadowsocks replay protection is effectively disabled: the IV/nonce uniqueness check is commented out, so a recorded AEAD packet is accepted for replay any number of times.
Affected code:
proxy/shadowsocks/validator.go:112-154—Validator.Get()never returnsErrIVNotUnique; the only check is commented out at line 148:ErrIVNotUnique(defined inconfig.go:29) is unreachable, and the error-handling branches inprotocol.go:81and:234are dead code.Additionally, for UDP (
proxy/shadowsocks/server.go:147-156), after the first packet setsinbound.User, every subsequent packet is decoded through a freshly constructedValidatorcontaining only that user — bypassing even a hypothetical dedup state for all packets after the first from a source.Impact
An on-path attacker records a legitimate client's AEAD packet (UDP, or the first TCP chunk) and replays it at will: the server decrypts and re-dispatches every copy — repeated outbound connections and UDP amplification through the proxy. AEAD integrity does not help here; nothing rejects duplicates.
This matches upstream Xray-core behavior (the check is disabled upstream too), but it contradicts the Shadowsocks AEAD practice of salt/IV deduplication.
Suggested fix
Validator.Get()(CheckIVfor non-AEAD, nonce dedup for AEAD), with a bounded per-user replay window (as in shadowsocks SIP004 implementations).server.go:147-156) checks subsequent packets against it instead of a freshValidator.