The API console built the upstream URL by concatenating a caller-controlled path onto a fixed API base. There was no host allow-list. A leading @ made the parser treat the official host as userinfo, so the real host came from the caller.
The proxy reflected status, headers, and body. On GET it followed redirects. An HTTPS redirect we controlled answered with a Location on plain HTTP to the Docker bridge, port of the gateway admin API. Egress left TLS and landed there. That admin API had no authentication.
What we proved
- Full read of the gateway admin API: internal services, routes, plugins, status, and the declarative config.
- OPTIONS on the same API advertised write methods. We wrote that down. We did not create a service.
What this is not
This is not a production payment. The money-movement issue on the same portal is a separate report. This one is the console proxy seeing the mesh.
Why a scanner misses it
No signature for @ userinfo in a JSON path field. No signature for "follow the redirect, drop TLS, hit the bridge address." The bug is three behaviors in a row.
Buyer takeaway: A developer console in front of a bank is part of the bank. Test the proxy as if it can see the mesh.