#141·hetty

Unauthenticated remote access to the admin UI and GraphQL API

Author: Ray0x01Created Apr 27, 2026Updated Apr 27, 2026

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:

go
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:

go
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:

http
GET /api/graphql/ HTTP/1.1
Host: <server>:8080

the 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:

go
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

  1. Start Hetty with default settings:
bash
hetty
  1. From another machine on the same network, browse to:
http://<hetty-ip>:8080/api/graphql/
  1. Observe that the GraphQL Playground is accessible without authentication.

  2. Send a GraphQL POST request:

http
POST /api/graphql/ HTTP/1.1