Senior · Gin services

A forged forwarded address bypasses a limit

A service trusts X-Forwarded-For from every peer and rate-limits by c.ClientIP. What can a direct client influence?

Try explaining this aloud before opening the answer. State your assumptions and trace a boundary case.

EXAMPLE · FRAGMENT UNLESS A COMPLETE PROGRAM IS SHOWN

go
package main

import (
	"fmt"
	"net/http/httptest"

	"github.com/gin-gonic/gin"
)

func main() {
	gin.SetMode(gin.TestMode)
	r := gin.New()
	if err := r.SetTrustedProxies(nil); err != nil {
		panic(err)
	}
	r.GET("/ip", func(c *gin.Context) { c.String(200, c.ClientIP()) })
	req := httptest.NewRequest("GET", "/ip", nil)
	req.RemoteAddr = "192.0.2.10:4321"
	req.Header.Set("X-Forwarded-For", "203.0.113.77")
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	fmt.Println(w.Body.String()) // 192.0.2.10, not the supplied header
}
Reveal a strong answer
  1. A reverse proxy may supply the original client address, but a direct client can also send X-Forwarded-For. If a Go service trusts forwarding headers from every peer, address-based controls can be bypassed. Configure exactly which proxy origins are trusted and make the edge replace or sanitize incoming forwarding headers. An IP address remains a network observation, not a user credential.

  2. Write down the chain of load balancers and ingress proxies. Restrict direct access to the service where practical, configure Gin trust and verify how the edge processes preexisting forwarding headers. Use TLS according to the actual termination boundary. Rate-limit authenticated identities and service capacity as well as addresses; many legitimate users can share one NAT address. With trusted proxies disabled, ClientIP uses the peer address and ignores the claimed forwarded client address. The documentation-only addresses are reserved example ranges. Behind a real controlled proxy, configure its actual narrow address ranges instead of copying these values or trusting all private networks.

  3. Trusting 0.0.0.0/0 or accepting a header called X-User is not authentication. Forwarded host and scheme can also affect generated URLs and redirects. Test a direct spoofed request, a legitimate proxy, multiple forwarded hops and IPv6. Keep proxy configuration immutable while the engine serves traffic and review it after topology changes.

Common trap

An HTTP header containing an address is not proof that the request passed through a trusted proxy.

Try it

Test a spoofed direct request and a legitimate controlled reverse proxy; identify which layer must sanitize the header chain.

Worked solution

A client can claim arbitrary forwarding information if all peers are trusted. Disable proxy trust when unused or configure narrow controlled proxy origins and edge header processing. Test actual peer versus forwarded hops and IPv6. Address-based controls remain imperfect because legitimate users share NATs and an IP is not an authenticated user; preserve explicit principal/resource authorization and service-capacity limits.

Change the constraint

How do forwarded scheme/host values affect generated links and redirect safety?

How did you do?

Self-assessment, not a compiler pass or interview score. Explain the reasoning unaided before marking understood.

Not marked. Progress stays on this browser, separate from course completion.

Primary references

Checked 2026-10-28. Use documentation for your pinned runtime, driver and tool version.