Irbisa · Cheatsheet
Networking & Security for Backend
TCP and the OSI model, DNS, TLS, HTTP/3 and QUIC, load balancers and proxies, WebSockets, CORS, password hashing, OAuth 2.0 and JWT, SSRF, mTLS
What are the layers of the OSI and TCP/IP models, and at which layer do IP, TCP, TLS, HTTP and a load balancer work?
What happens, step by step, between typing
https://example.com/ordersinto a browser and the first byte of the response?How does HTTPS differ from HTTP, what does a TLS handshake do, and when would you pick UDP over TCP?
What is CORS, which requests trigger a preflight
OPTIONS, and why does CORS not protect an API fromcurlor another server?How does a WebSocket connection start from an HTTP request, and what must proxies and load balancers in front of a Go service support to keep it open?
// Registered as mux.HandleFunc("GET /ws", chat).func chat(w http.ResponseWriter, r *http.Request) { // Checks the Upgrade headers and Origin, then answers 101 Switching Protocols. c, err := websocket.Accept(w, r, &websocket.AcceptOptions{ OriginPatterns: []string{"app.example.com"}, // browsers send Origin; CORS does not apply here })…How does TCP open a connection with the three-way handshake and close it, and why does a busy client pile up sockets in
TIME_WAIT?How does DNS resolution work, and why can a Go service keep sending traffic to an old IP for minutes after the record changes?
How does a TLS client decide that a certificate really belongs to
api.example.com, and what should you do instead ofInsecureSkipVerifyfor a private CA?// The billing API uses a certificate from the company CA, which is not in// the system pool, so calls fail with "certificate signed by unknown authority".func newBillingClient(companyCA []byte) (*http.Client, error) { pool, err := x509.SystemCertPool() if err != nil { return nil, err…What does HTTP/3 over QUIC change compared with HTTP/2 over TCP (handshake, head-of-line blocking, connection migration), and does a Go API need it?
What is the difference between an L4 and an L7 load balancer, and what can each one see and do with a request?
Forward proxy vs reverse proxy: what is the difference, and how does a Go service behind one get the client's real IP without trusting a spoofed
X-Forwarded-For?// The address ranges of our own load balancers and ingress proxies.var trustedProxies = []netip.Prefix{netip.MustParsePrefix("10.0.0.0/8")} func trusted(ip netip.Addr) bool { return slices.ContainsFunc(trustedProxies, func(p netip.Prefix) bool { return p.Contains(ip) })}…How should a Go service store user passwords, why is SHA-256 the wrong tool, and what do
bcryptandargon2idfromgolang.org/x/cryptodo differently?// bcrypt: the salt and the cost travel inside the result, "$2a$12$<salt><hash>".func hashPassword(pw string) (string, error) { h, err := bcrypt.GenerateFromPassword([]byte(pw), 12) // ErrPasswordTooLong past 72 bytes return string(h), err}…JWT or server-side sessions: what are the trade-offs, where should a browser keep the token, and what is IDOR?
Find the bug: a JWT minted by a test script two years ago still authenticates against production.
var secret = []byte(os.Getenv("JWT_SECRET")) // userID authenticates every request to the orders API.func userID(raw string) (string, error) { tok, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) { return secret, nil }) if err != nil { return "", err } return tok.Claims.GetSubject()}How does the OAuth 2.0 authorization code flow with PKCE work, and what does OpenID Connect add on top of OAuth?
var conf = &oauth2.Config{ ClientID: "orders-web", ClientSecret: "from-the-secret-store", // a backend is a confidential client RedirectURL: "https://app.example.com/callback", Scopes: []string{oidc.ScopeOpenID, "email"}, Endpoint: oauth2.Endpoint{AuthURL: "https://id.example.com/authorize", TokenURL: "https://id.example.com/token"},…This function checks a webhook's HMAC signature before the handler trusts the body. Which two security bugs does it have, and how do you fix them?
// The provider sends X-Signature: hex(HMAC-SHA256(secret, body)).func verifyWebhook(r *http.Request, secret []byte) ([]byte, error) { body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20)) if err != nil { return nil, err } mac := hmac.New(sha256.New, secret) mac.Write(body) want := hex.EncodeToString(mac.Sum(nil)) if r.Header.Get("X-Signature") != want { return nil, errors.New("bad signature") } return body, nil}Find the bug: a file download endpoint lets any user read
/etc/passwdand the service's own config file.// filesDir is "/srv/app/uploads"; the config lives in /srv/app/config.yaml.// Registered as mux.HandleFunc("GET /download", download).func download(w http.ResponseWriter, r *http.Request) { name := r.URL.Query().Get("name") // "report.pdf" http.ServeFile(w, r, filepath.Join(filesDir, name))}Your service fetches a user-supplied webhook URL. What is SSRF, and how do you block
169.254.169.254and internal hosts, including through DNS rebinding?var cgnat = netip.MustParsePrefix("100.64.0.0/10") // carrier-grade NAT, not in IsPrivate // Control runs on every dial, after DNS, with the IP about to be connected,// so a rebinding answer or a redirect to 10.0.0.5 is checked as well.func publicOnly(network, address string, _ syscall.RawConn) error { ap, err := netip.ParseAddrPort(address)…How does mutual TLS between two Go services work, and which
tls.Configfields must each side set so that neither talks to an impostor?// Server: only callers with a certificate from our CA, and only the allowed ones.func serverTLS(cert tls.Certificate, clientCAs *x509.CertPool, allowed []string) *tls.Config { return &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tls.RequireAndVerifyClientCert, // RequireAnyClientCert does not verify ClientCAs: clientCAs,…