Skip to content

fix: enforce relay control and message size limit - #4

Merged
dndungu merged 1 commit into
mainfrom
security/003-followup
Jul 4, 2026
Merged

fix: enforce relay control and message size limit#4
dndungu merged 1 commit into
mainfrom
security/003-followup

Conversation

@dndungu

@dndungu dndungu commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to security/003-followup — deep-review-003's SMTP open-relay and DATA-size-DoS Design-Critical/High findings were reported fixed by that run's predicates, but both predicates just grepped for strings (LocalDomains|relay|s.auth, maxMessageSize) that were already present pre-fix (a field declared and defaulted, never enforced). Closes both for real:

  • handleRcpt accepted RCPT TO for any recipient with no auth or locality check (open relay). Now: an unauthenticated session may only deliver to a domain this server hosts (localDomains); an authenticated session may relay anywhere (standard MSA/MX behavior).
  • handleData never consulted maxMessageSize while buffering the DATA body (unbounded memory growth). Now enforced while reading, draining without buffering past the terminator on overflow so the connection stays protocol-consistent (a response is only valid after the DATA terminator per RFC 5321).

Note: this repo (like the rest of the email stack) is not deployed to production per deep-review-003, and has no CI test/lint workflow configured at all — flagging as pre-existing, out of scope here.

Test plan

  • GOWORK=off go build ./..., go vet ./... clean, full suite green
  • New regression tests: relay denied (unauth + non-local), relay allowed (unauth + local, and authenticated + non-local), oversized message rejected with 552 and session still usable afterward
  • Existing TestServerMessageDelivery/TestSessionHandleFullTransaction updated to configure a local domain, matching realistic non-authenticated inbound delivery

handleRcpt accepted RCPT TO for any recipient with no auth or locality
check (open relay); handleData never consulted maxMessageSize while
buffering the DATA body (unbounded memory growth). Adds a localDomains-
based relay check (unauthenticated sessions may only deliver to a domain
this server hosts; authenticated sessions may relay anywhere, matching
standard MSA/MX behavior) and enforces maxMessageSize while reading DATA,
draining without buffering past the terminator on overflow so the
connection stays protocol-consistent.
@dndungu
dndungu merged commit 26e46e9 into main Jul 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant