HIGH dns rebindingchigo

Dns Rebinding in Chi (Go)

Dns Rebinding in Chi with Go — how this specific combination creates or exposes the vulnerability

DNS Rebinding is an application-layer attack where an attacker manipulates DNS responses to make a victim’s browser believe a trusted host resolves to an internal IP address (e.g., 127.0.0.1). When using the Chi router with Go, this can expose internal services because Chi does not inherently protect against hosts that change their IP after the initial TLS or HTTP handshake. A typical scenario: an attacker registers a domain (example.com) pointing to an external attacker server, then serves a page that uses JavaScript to repeatedly resolve the domain to 127.0.0.1. The victim’s browser sends authenticated requests to example.com, but DNS rebinding redirects them to localhost. If your Go service running Chi listens on 127.0.0.1 and trusts same-origin requests, the attacker can bypass network-level isolation.

Chi’s routing and middleware stack do not automatically validate that the request host matches an expected set of public endpoints. If you rely on host-based restrictions or assume that localhost is unreachable from outside, DNS Rebinding can subvert those assumptions. For example, a health check endpoint exposed via Chi on :8080 might be intended for internal monitoring, but with DNS Rebinding, an authenticated user can cause the browser to issue requests that resolve to localhost, potentially accessing internal endpoints. This is especially relevant when using middleware that inspects Host headers for routing or tenant isolation without corroborating the resolved IP address.

In a black-box scan, middleBrick tests for SSRF and DNS Rebinding by probing endpoints that interact with internal network resources. If your Chi application exposes administrative routes on localhost or uses the request Host header to make internal HTTP calls, these checks can surface the risk. Because the attack leverages standard HTTP and DNS behavior, it bypasses perimeter defenses that assume perimeter controls are sufficient. Middleware in Chi that conditionally allows traffic based on host strings without validating the resolved IP can inadvertently create a pathway for unauthorized internal access.

Go-Specific Remediation in Chi — concrete code fixes

Remediation focuses on explicit host validation and avoiding reliance on network position. In Chi, use a custom host validation middleware that resolves the request’s TCP remote address and compares it against an allowlist, rather than trusting the Host header alone. For services that must accept external traffic, restrict allowed hostnames to a strict set and reject requests where the resolved IP is in the private range unless explicitly permitted.

Example: Host validation middleware for Chi

package main

import (
	"context"
	"net"
	"net/http"
	"strings"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
)

// allowedHosts is an allowlist of public hostnames/IPs that are expected.
var allowedHosts = map[string]bool{
	"api.example.com": true,
	"192.0.2.1":       true, // example public IP
}

// hostValidationMiddleware rejects requests with unexpected Host headers
// or connections from unexpected resolved IPs.
func hostValidationMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Validate Host header
		host := r.Host
		if !allowedHosts[host] {
			http.Error(w, "host not allowed", http.StatusForbidden)
			return
		}

		// Optionally validate remote address if you expect specific source IPs
		if remoteHost, _, err := net.SplitHostPort(r.RemoteAddr); err == nil {
			if ip := net.ParseIP(remoteHost); ip != nil && ip.IsLoopback() {
				// Reject loopback connections from external-facing endpoints
				// unless you have a specific reason to allow them.
				http.Error(w, "loopback connections not permitted", http.StatusForbidden)
				return
			}
		}

		next.ServeHTTP(w, r)
	})
}

func main() {
	r := chi.NewRouter()
	r.Use(middleware.RealIP)
	r.Use(hostValidationMiddleware)

	r.Get("/healthz", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("ok"))
	})

	// Example endpoint that should not be exposed to rebinding attacks
	r.Get("/internal/status", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("internal status"))
	})

	http.ListenAndServe(":8080", r)
}

This approach explicitly checks both the Host header and the resolved remote IP, reducing the risk that a DNS Rebinding attack will succeed by making localhost reachable through a trusted hostname. Avoid using the Host header alone to determine access control, and do not assume that binding to 127.0.0.1 will protect endpoints that should remain internal.

Where your application must call internal services based on incoming requests, prefer resolving targets via a trusted configuration or service discovery rather than deriving hostnames from request metadata. middleBrick’s scans can highlight endpoints where host-based routing or internal resolution might be abused, allowing you to tighten validation before attackers exploit these pathways.

Frequently Asked Questions

Can DNS Rebinding bypass CORS and same-origin policies in a Chi-based Go service?
Yes. If your Chi application relies solely on CORS headers or browser same-origin checks without validating the resolved IP, a malicious site can make the victim’s browser issue requests that appear to originate from an allowed hostname but reach internal IPs. Defense-in-depth with server-side host and IP validation is required.
Does middleBrick detect DNS Rebinding risks in Chi applications?
Yes. middleBrick scans API endpoints and tests for conditions that enable DNS Rebinding, such as host-based routing without IP validation and exposure of internal endpoints. Findings include severity, context, and remediation guidance to harden your Chi-based Go service.