net/go.book
All Parts Marketing

Common Network Attacks (DoS, MITM, Spoofing, etc.)

"A pickpocket, a con artist, and a mob blocking the door all want different things, but they all exploit the same crowded street. Network attacks are no different — the wire is the crowded street."


A Field Guide, Not a Weapons Manual

This chapter catalogs the attack categories you'll hear about constantly in networking and security work: denial of service, man-in-the-middle, and spoofing, plus a few close relatives. The goal is recognition and defense — understanding how each attack works mechanically so you can spot the conditions that enable it and close them, not a step-by-step guide to causing outages on infrastructure you don't own.

Authorized use only
Testing any of the techniques described below — flooding a service, intercepting traffic, forging packets — is only appropriate against systems you own or a target explicitly covered by a signed authorization (a lab, a CTF, a scoped penetration test). Doing this against networks you don't control is illegal in most jurisdictions and can cause real, unintended damage.


Denial of Service (DoS) and Distributed Denial of Service (DDoS)

The goal of a DoS attack is simple: make a service unavailable to legitimate users, either by exhausting a resource it depends on or by overwhelming its capacity.

  • Volumetric attacks flood a target with more traffic than its link or infrastructure can handle — the network equivalent of jamming every phone line at once.
  • Protocol attacks abuse the mechanics of a protocol itself. A classic example is a SYN flood: the attacker sends many TCP SYN packets and never completes the handshake, exhausting the server's table of half-open connections.
  • Application-layer attacks target expensive operations at the application level — repeatedly requesting a page that triggers a slow database query, for instance — using comparatively little bandwidth to cause a lot of load.
  • Distributed (DDoS) attacks spread the traffic across many source hosts, often a botnet, making the flood harder to block with simple source-IP filtering.

Defenses: rate limiting, connection timeouts, SYN cookies (handled by most modern OS TCP stacks), upstream scrubbing services, and — architecturally — designing services so a single slow dependency can't exhaust all available worker capacity (bulkheads, circuit breakers, sensible timeouts on every net.Conn and http.Client).


Man-in-the-Middle (MITM)

A MITM attack places the attacker on the path between two communicating parties, able to read, and often alter, traffic that both sides believe is private and direct.

Common enablers:

  • ARP spoofing on a local network: the attacker sends forged ARP replies so that traffic meant for the real gateway or host is routed through the attacker's machine instead.
  • Rogue Wi-Fi access points that mimic a trusted network name, so victims connect directly through the attacker.
  • DNS spoofing/cache poisoning, which redirects a victim to an attacker-controlled server that impersonates the real one (see below).
  • TLS stripping or downgrade attempts, where an attacker intercepts an initial unencrypted request and prevents the upgrade to HTTPS, keeping the victim on plaintext.

Defenses: TLS with proper certificate validation (Chapters 5.11–5.12) closes the door on reading or altering traffic even if an attacker sits on the path; HSTS prevents downgrade from HTTPS to HTTP; static ARP entries or port security on switches mitigate ARP spoofing on sensitive segments.


Spoofing

Spoofing means forging an identifying field so traffic appears to come from somewhere — or someone — it doesn't.

  • IP spoofing: forging the source address in a packet header. Often used to hide the true origin of an attack, or as a building block for reflection/amplification DDoS.
  • ARP spoofing: covered above, forging the mapping between an IP and a MAC address on a local segment.
  • DNS spoofing: returning a forged DNS response so a hostname resolves to an attacker-controlled IP instead of the legitimate one.
  • Email/caller-ID style spoofing: outside pure networking, but the same principle — forging a field a human trusts.

Defenses: ingress/egress filtering at network borders (rejecting packets whose source address couldn't legitimately originate from that link — BCP 38), DNSSEC for authenticated DNS responses, and — again — TLS, since a spoofed peer still cannot present a valid certificate for a domain it doesn't control.


Session Hijacking and Replay Attacks

Once two parties are talking, an attacker who obtains a valid session token or captures a valid message can sometimes reuse it:

  • Session hijacking — stealing or predicting a session identifier (a cookie, a token) to impersonate an already-authenticated user.
  • Replay attacks — capturing a legitimate message (like an authentication handshake) and resending it later to repeat its effect.

Defenses: short-lived tokens, binding sessions to additional context (IP, TLS channel), nonces or timestamps that make a captured message unusable a second time, and transport encryption so the token can't be captured in the first place.


A Small Defensive Pattern in Go

Most of these attacks are mitigated architecturally rather than with a single snippet, but a simple, concrete example is a per-client rate limiter — a direct defense against both application-layer DoS and brute-force-style abuse:

package main

import (
	"net"
	"sync"
	"time"
)

// limiter tracks a simple token count per client address, refilled
// once per interval. It's a minimal illustration, not a production
// rate limiter (consider golang.org/x/time/rate for real services).
type limiter struct {
	mu     sync.Mutex
	tokens map[string]int
	max    int
}

func newLimiter(max int) *limiter {
	return &limiter{tokens: make(map[string]int), max: max}
}

func (l *limiter) allow(addr net.Addr) bool {
	l.mu.Lock()
	defer l.mu.Unlock()
	host, _, _ := net.SplitHostPort(addr.String())
	if _, seen := l.tokens[host]; !seen {
		l.tokens[host] = l.max
	}
	if l.tokens[host] <= 0 {
		return false
	}
	l.tokens[host]--
	return true
}

func (l *limiter) refill(host string) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.tokens[host] = l.max
}

func main() {
	l := newLimiter(5)
	go func() {
		for range time.Tick(time.Second) {
			l.mu.Lock()
			hosts := make([]string, 0, len(l.tokens))
			for host := range l.tokens {
				hosts = append(hosts, host)
			}
			l.mu.Unlock()
			for _, host := range hosts {
				l.refill(host)
			}
		}
	}()
	_ = l // wire l.allow(conn.RemoteAddr()) into your Accept loop
}

The specific numbers matter less than the pattern: every connection-accepting service should have an answer to "what happens if one source sends far more requests than a normal client would."


Frequently Asked Questions

If I never see SYN cookies or rate limiters in my own code, does that mean my service is vulnerable to DoS? Not necessarily — SYN cookies are usually handled transparently by the OS TCP stack, not by your application, so you're already benefiting from that defense without writing a line of code. Application-layer protections like rate limiting and sensible timeouts, though, are on you to add explicitly; a net.Listen loop with no connection cap or per-client throttling is exactly the gap this chapter's rate-limiter example is meant to close.

Why does TLS keep showing up as the defense for MITM, spoofing, and session hijacking? Because all three attacks ultimately depend on the attacker being able to either read plaintext or impersonate a party convincingly, and a properly validated TLS connection denies both: it encrypts the channel and requires the peer to present a certificate it couldn't forge without the private key. That's not a coincidence — it's why Chapters 5.11 and 5.12 dedicate two full chapters to TLS and the PKI that makes its trust model work.

Is ARP spoofing something I should worry about over the public internet? No — ARP only operates on a local network segment, so ARP spoofing requires the attacker to already be on the same LAN or Wi-Fi network as the victim. That's exactly why it pairs so often with rogue access points in the MITM section above: the attacker's real first step is getting onto your local segment, and ARP spoofing is what they do once they're there.

I want to try building a small SYN-flood or rate-limit test — where's the boundary of "safe to experiment with"? Anything from this chapter is fine to build and run against a lab machine, a local VM, or a service you stood up yourself specifically for testing — the rate-limiter example above is meant to be wired into your own Accept loop and hammered with your own test traffic. The line is authorization: the moment the target is a system you don't own and haven't been explicitly cleared to test, the same code stops being a learning exercise and becomes the attack this chapter is teaching you to defend against.


Recognizing the Pattern

Notice that nearly every defense above reduces to a small set of ideas repeated throughout this book: authenticate and encrypt (TLS), validate what you trust implicitly (source addresses, DNS responses), and bound what any single actor can consume (timeouts, rate limits, connection caps). Chapter 5.4 puts you on the other side of this equation — using Go to discover what's exposed on a network before an attacker does.