Pentesting gRPC-Web
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Rápido repaso del protocolo y superficie de ataque
- Transporte: gRPC‑Web speaks a browser‑compatible variant of gRPC over HTTP/1.1 or HTTP/2 via a proxy (Envoy/APISIX/grpcwebproxy/etc.). Only unary and server‑streaming calls are supported.
- Content-Types que verás:
- application/grpc-web (binary framing)
- application/grpc-web-text (base64-encoded framing for HTTP/1.1 streaming)
- Framing: cada mensaje va precedido de un header gRPC de 5 bytes (1 byte de flags + 4 bytes de longitud). En gRPC‑Web, los trailers (grpc-status, grpc-message, …) se envían dentro del body como un frame especial: primer byte con el MSB establecido (0x80) seguido de una longitud y un bloque de encabezados al estilo HTTP/1.1.
- Encabezados de solicitud comunes: x-grpc-web: 1, x-user-agent: grpc-web-javascript/…, grpc-timeout, grpc-encoding. Las respuestas exponen grpc-status/grpc-message vía trailers/body frames y a menudo mediante Access-Control-Expose-Headers para navegadores.
- Middleware relevantes para seguridad que suelen estar presentes:
- Envoy grpc_web filter and gRPC‑JSON transcoder (HTTP<->gRPC bridge)
- Nginx/APISIX gRPC‑Web plugins
- CORS policies on the proxy
Qué significa esto para atacantes:
- Puedes construir requests a mano (binario o texto base64), o dejar que las herramientas los generen/encodifiquen.
- Errores de CORS en el proxy pueden permitir llamadas gRPC‑Web cross‑site autenticadas (similar a problemas clásicos de CORS).
- Los bridges de JSON transcoding pueden exponer inadvertidamente métodos gRPC como endpoints HTTP no autenticados si las rutas/autenticación están mal configuradas.
Testing gRPC‑Web desde la CLI
Más fácil: buf curl (speaks gRPC‑Web natively)
- List methods via reflection (if enabled):
# list methods (uses reflection)
buf curl --protocol grpcweb https://host.tld --list-methods
- Llamar a un método con entrada JSON, manejando automáticamente el framing y los headers de gRPC‑Web:
buf curl --protocol grpcweb \
-H 'Origin: https://example.com' \
-d '{"field":"value"}' \
https://host.tld/pkg.svc.v1.Service/Method
- Si reflection está deshabilitado, proporciona un schema/descriptor set con –schema o apunta a archivos .proto locales. See buf help curl.
Raw con curl (cabeceras manuales + framed body)
Para el modo binario (application/grpc-web), envía un framed payload (prefijo de 5 bytes + protobuf message). Para el modo texto, codifica en base64 el framed payload.
# Build a protobuf message, then gRPC-frame it (1 flag byte + 4 length + msg)
# Example using protoscope to compose/edit the message and base64 for grpc-web-text
protoscope -s msg.txt | python3 grpc-coder.py --encode --type grpc-web-text | \
tee body.b64
curl -i https://host.tld/pkg.svc.v1.Service/Method \
-H 'Content-Type: application/grpc-web-text' \
-H 'X-Grpc-Web: 1' \
-H 'X-User-Agent: grpc-web-javascript/0.1' \
--data-binary @body.b64
Consejo: Forzar el modo base64/text con application/grpc-web-text cuando los intermediarios HTTP/1.1 rompen la transmisión binaria.
Comprobar el comportamiento de CORS (preflight + response)
- Preflight:
curl -i -X OPTIONS https://host.tld/pkg.svc.v1.Service/Method \
-H 'Origin: https://evil.tld' \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: content-type,x-grpc-web,x-user-agent,grpc-timeout'
- Una configuración vulnerable suele reflejar un Origin arbitrario y enviar Access-Control-Allow-Credentials: true, permitiendo llamadas autenticadas cross‑site. También verifica que Access-Control-Expose-Headers incluya grpc-status, grpc-message (muchas implementaciones exponen estos para client libs).
Para técnicas genéricas para abusar de CORS, consulta CORS - Misconfigurations & Bypass.
Manipulación de payloads de gRPC‑Web
gRPC‑Web usa Content-Type: application/grpc-web-text como un stream de frames gRPC envuelto en base64 para compatibilidad con navegadores. Puedes decodificar/modificar/recodificar los frames para alterar campos, invertir flags o inyectar payloads.
Usa la herramienta gprc-coder (y su extensión para Burp) para acelerar los round‑trips.
Manual con gGRPC Coder Tool
- Decodifica el payload:
echo "AAAAABYSC0FtaW4gTmFzaXJpGDY6BVhlbm9u" | python3 grpc-coder.py --decode --type grpc-web-text | protoscope > out.txt
- Editar el contenido del payload decodificado
nano out.txt
2: {"Amin Nasiri Xenon GRPC"}
3: 54
7: {"<script>alert(origin)</script>"}
- Codifica el nuevo payload
protoscope -s out.txt | python3 grpc-coder.py --encode --type grpc-web-text
- Usar la salida en el interceptor de Burp:
AAAAADoSFkFtaW4gTmFzaXJpIFhlbm9uIEdSUEMYNjoePHNjcmlwdD5hbGVydChvcmlnaW4pPC9zY3JpcHQ+
Manual con gRPC‑Web Coder Burp Suite Extension
Puedes usar gRPC‑Web Coder Burp Suite Extension en gRPC‑Web Pentest Suite, que es más sencillo. Puedes leer las instrucciones de instalación y uso en su repositorio.
Analizando archivos JavaScript de gRPC‑Web
Las apps web que usan gRPC‑Web incluyen al menos un bundle JS/TS generado. Haz ingeniería inversa sobre ellos para extraer servicios, métodos y la estructura de los mensajes.
- Prueba usando gRPC-Scan para parsear los bundles.
- Busca rutas de métodos como /
. / , números/tipos de campos de mensaje y interceptores personalizados que añaden auth headers.
- Descarga el archivo JavaScript gRPC‑Web
- Escanéalo con grpc-scan.py:
python3 grpc-scan.py --file main.js
- Analizar la salida y probar los nuevos endpoints y nuevos services:
Output:
Found Endpoints:
/grpc.gateway.testing.EchoService/Echo
/grpc.gateway.testing.EchoService/EchoAbort
/grpc.gateway.testing.EchoService/NoOp
/grpc.gateway.testing.EchoService/ServerStreamingEcho
/grpc.gateway.testing.EchoService/ServerStreamingEchoAbort
Found Messages:
grpc.gateway.testing.EchoRequest:
+------------+--------------------+--------------+
| Field Name | Field Type | Field Number |
+============+====================+==============+
| Message | Proto3StringField | 1 |
+------------+--------------------+--------------+
| Name | Proto3StringField | 2 |
+------------+--------------------+--------------+
| Age | Proto3IntField | 3 |
+------------+--------------------+--------------+
| IsAdmin | Proto3BooleanField | 4 |
+------------+--------------------+--------------+
| Weight | Proto3FloatField | 5 |
+------------+--------------------+--------------+
| Test | Proto3StringField | 6 |
+------------+--------------------+--------------+
| Test2 | Proto3StringField | 7 |
+------------+--------------------+--------------+
| Test3 | Proto3StringField | 16 |
+------------+--------------------+--------------+
| Test4 | Proto3StringField | 20 |
+------------+--------------------+--------------+
grpc.gateway.testing.EchoResponse:
+--------------+--------------------+--------------+
| Field Name | Field Type | Field Number |
+==============+====================+==============+
| Message | Proto3StringField | 1 |
+--------------+--------------------+--------------+
| Name | Proto3StringField | 2 |
+--------------+--------------------+--------------+
| Age | Proto3IntField | 3 |
+--------------+--------------------+--------------+
| IsAdmin | Proto3BooleanField | 4 |
+--------------+--------------------+--------------+
| Weight | Proto3FloatField | 5 |
+--------------+--------------------+--------------+
| Test | Proto3StringField | 6 |
+--------------+--------------------+--------------+
| Test2 | Proto3StringField | 7 |
+--------------+--------------------+--------------+
| Test3 | Proto3StringField | 16 |
+--------------+--------------------+--------------+
| Test4 | Proto3StringField | 20 |
+--------------+--------------------+--------------+
| MessageCount | Proto3IntField | 8 |
+--------------+--------------------+--------------+
grpc.gateway.testing.ServerStreamingEchoRequest:
+-----------------+-------------------+--------------+
| Field Name | Field Type | Field Number |
+=================+===================+==============+
| Message | Proto3StringField | 1 |
+-----------------+-------------------+--------------+
| MessageCount | Proto3IntField | 2 |
+-----------------+-------------------+--------------+
| MessageInterval | Proto3IntField | 3 |
+-----------------+-------------------+--------------+
grpc.gateway.testing.ServerStreamingEchoResponse:
+------------+-------------------+--------------+
| Field Name | Field Type | Field Number |
+============+===================+==============+
| Message | Proto3StringField | 1 |
+------------+-------------------+--------------+
grpc.gateway.testing.ClientStreamingEchoRequest:
+------------+-------------------+--------------+
| Field Name | Field Type | Field Number |
+============+===================+==============+
| Message | Proto3StringField | 1 |
+------------+-------------------+--------------+
grpc.gateway.testing.ClientStreamingEchoResponse:
+--------------+----------------+--------------+
| Field Name | Field Type | Field Number |
+==============+================+==============+
| MessageCount | Proto3IntField | 1 |
+--------------+----------------+--------------+
Advertencias sobre bridging y transcodificación JSON
Muchas implementaciones colocan un proxy Envoy (o similar) delante del servidor gRPC:
- El filtro grpc_web convierte HTTP/1.1 POSTs en HTTP/2 gRPC.
- El gRPC‑JSON Transcoder expone métodos gRPC como endpoints HTTP JSON cuando las opciones .proto (google.api.http) están presentes.
Desde la perspectiva de pentesting:
- Intenta llamadas HTTP JSON directas a /
. / con application/json cuando un transcoder está habilitado (auth/route mismatches are common):
curl -i https://host.tld/pkg.svc.v1.Service/Method \
-H 'Content-Type: application/json' \
-d '{"field":"value"}'
- Revisa si métodos/parametros desconocidos son rechazados o simplemente se pasan. Algunas configuraciones reenvían rutas no coincidentes upstream, ocasionalmente evitando la auth o la validación de solicitudes.
- Observa x-envoy-original-path y los encabezados relacionados añadidos por proxies. Los upstreams que confían en estos pueden ser abusables si el proxy no los sanea.
Referencias
- Hacking into gRPC‑Web Article by Amin Nasiri
- gRPC‑Web Pentest Suite
- gRPC‑Web protocol notes (PROTOCOL‑WEB.md)
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
HackTricks

