feat: source-port-trust smell — the sender picks their own source port (v1.28.0) - #42
Merged
Conversation
…t (v1.28.0) An inbound ACCEPT keyed on --sport (nft `udp sport`) with no destination port pinned trusts the one packet field the sender types in for free: nmap -g/--source-port exists precisely to walk through rules like this. The pre-conntrack "let replies back in" idiom, flagged with three honest exemptions: dport-pinned rules (the service is the gate), ESTABLISHED/ RELATED rules (conntrack is the gate), and anything not reachable from INPUT/FORWARD (on the OUTPUT side the sport is the host's own port — stateless egress rules legitimately match it; BFS over jumps decides). Blocking by sport stays unflagged — wide caution ok, borrowed trust not. Completes the spoofable-trust trilogy: MAC, bogon IP, source port. The sloppy router gains the perfect backstory: its missing conntrack rule broke DNS, so the admin "fixed" it with --sport 53 -j ACCEPT — missing-established-accept and this smell now fire as cause and effect. Linter goes from 36 to 37 smells. 165 tests (4 new). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Smell #37:
source-port-trustAn inbound ACCEPT keyed on the source port (
--sport 53, nftudp sport 53) with no destination port pinned. The source port is the cheapest field in the packet to forge — it is whatever socket the sender binds, andnmap -g/--source-portexists precisely to walk through rules like this — so "from port 53" admits anyone who remembers to set their source port, to every local port.It is the pre-conntrack idiom for letting replies back in (DNS answers, active-FTP data); the modern spelling is
ct state established,related accept.Exemptions that keep it honest
unused-chainmachinery): on the OUTPUT side the sport is the host's own port and stateless egress rules legitimately match it (pinned by test).mac-based-trustandbogon-source-accept. This completes the spoofable-trust trilogy (MAC, bogon IP, source port).Sample
The sloppy router earns the perfect backstory: its missing conntrack rule broke DNS, so the admin "fixed" it the pre-conntrack way —
--sport 53 -j ACCEPT.missing-established-acceptand this smell now fire as cause and effect.Verificado en local
npm test: 165/165 (4 tests nuevos: fires/spares, dport+established exemptions, OUTPUT vs user-chain direction, nft spelling)npm run lint: limpioLinter: 36 → 37 smells.
🤖 Generated with Claude Code