Simple HTTP forward proxy in Go with basic SSRF protections.
- Accepts incoming HTTP requests and forwards them to a target URL.
- Supports methods:
GET,POST,PUT,PATCH,DELETE,HEAD. - Reads target from query parameter
urlor headerX-Target-URL. - Blocks localhost, private, link-local, multicast, and other reserved IP ranges.
- Rejects unsupported methods and hop-by-hop headers.
- Leaves
X-Forwarded-Foruntouched.
- Go
1.26.1or newer (as declared ingo.mod).
go run .The server listens on :8080 by default.
To start on a custom port:
go run . -port 9090To require an auth token in X-Fwd-Authorization:
go run . -auth-token 'my-secret-token'Send a request to the proxy and provide the destination URL:
curl "http://localhost:8080/?url=https://httpbin.org/get"You can also pass the target in a header:
curl -H "X-Target-URL: https://httpbin.org/anything" "http://localhost:8080/"If started with -auth-token, include the auth header:
curl \
-H "X-Fwd-Authorization: my-secret-token" \
-H "X-Target-URL: https://httpbin.org/get" \
"http://localhost:8080/"Forward a JSON POST body:
curl -X POST \
-H "Content-Type: application/json" \
-H "X-Target-URL: https://httpbin.org/post" \
-d '{"hello":"world"}' \
"http://localhost:8080/"- Upstream response status code is preserved.
- Upstream response body is streamed back to the client.
- Hop-by-hop headers are stripped from both request and response.
- Only
httpandhttpstarget schemes are allowed. - Target URLs with userinfo (
user:pass@host) are rejected. localhostand.localhosthosts are blocked.- Direct IP targets are validated against blocked ranges.
- DNS-resolved IPs are validated before dialing.
- Maximum incoming request body size is
10 MiB.
These checks help reduce SSRF risk but do not replace network-level egress controls.
Configuration is defined in main.go constants and CLI flags:
-portCLI flag (default8080)-auth-tokenCLI flag (default empty, disabled)FWD_PROXY_AUTH_TOKENenv var (used when-auth-tokenis not set)maxRequestBody(default10 MiB)upstreamTimeout(default30s)
go test ./...No tests are currently included.