Unauthenticated remote access to the admin UI and GraphQL API
Unauthenticated Remote Access to Admin UI and GraphQL API
Summary
Hetty exposes its admin UI and GraphQL control plane to remote unauthenticated users when started with the default listener address :8080.
The issue is caused by a permissive admin-route matcher that treats ordinary non-CONNECT requests as local admin traffic. As a result, a remote user who can reach the Hetty port can access:
- the web admin interface
- the GraphQL Playground
- the GraphQL API
Because the GraphQL API exposes privileged control-plane operations, this allows unauthorized users to read proxy data and control parts of the application remotely.
Severity
High
This is a security boundary failure affecting a tool that is expected to be locally administered. Even though some downstream actions are intentional product features, exposing the control plane remotely without authentication is a serious vulnerability.
Affected Component
- Admin UI routing
- GraphQL API exposure
Relevant code:
Technical Details
Hetty defaults to:
fs.StringVar(&cmd.addr, "addr", ":8080", "TCP address to listen on, in the form \"host:port\".")This causes the HTTP server to listen on all interfaces unless the operator explicitly overrides it.
The admin router then uses the following matcher logic:
return strings.EqualFold(host, hostname) ||
req.Host == "hetty.proxy" ||
req.Host == fmt.Sprintf("%v:%v", "localhost", listenPort) ||
req.Host == fmt.Sprintf("%v:%v", listenHost, listenPort) ||
req.Method != http.MethodConnect && !strings.HasPrefix(req.RequestURI, "http://")The final condition is overly broad. For a normal browser or HTTP client request such as:
GET /api/graphql/ HTTP/1.1
Host: <server>:8080the RequestURI is /api/graphql/, which does not start with http://, so the request is routed to the admin subrouter even when it comes from a remote host.
The GraphQL API is exposed without authentication:
router.Methods("POST").Handler(handler.NewDefaultServer(...))
router.Methods("GET").Handler(playground.Handler("GraphQL Playground", gqlEndpoint))Impact
A remote unauthenticated attacker who can reach the Hetty listener can:
- access the admin interface
- access the GraphQL Playground
- query project and proxy state
- read captured request and response metadata and bodies
- modify interception and project settings
- invoke other privileged control-plane operations exposed by GraphQL
For a local security proxy tool, these actions should not be available to arbitrary network peers by default.
Steps to Reproduce
- Start Hetty with default settings:
hetty- From another machine on the same network, browse to:
http://<hetty-ip>:8080/api/graphql/Observe that the GraphQL Playground is accessible without authentication.
Send a GraphQL POST request:
POST /api/graphql/ HTTP/1.1Source: dstotijn/hetty