diff --git a/src/pentesting-web/grpc-web-pentest.md b/src/pentesting-web/grpc-web-pentest.md
index 3ea9c8e6712..2b52bfc837b 100644
--- a/src/pentesting-web/grpc-web-pentest.md
+++ b/src/pentesting-web/grpc-web-pentest.md
@@ -1,155 +1,251 @@
-# Pentesting gRPC-Web
-
-{{#include ../banners/hacktricks-training.md}}
-
-## **Manipulating gRPC-Web Payloads**
-
-gRPC-Web uses Content-Type: `application/grpc-web-text` in requests which is kind of protobuf in base64 encoded form, you can use [gprc-coder](https://github.com/nxenon/grpc-pentest-suite) tool ,and you can also install its [Burp Suite Extension](https://github.com/nxenon/grpc-pentest-suite).
-
-### **Manual with gGRPC Coder Tool**
-
-1. First decode the payload:
-
-```bash
-echo "AAAAABYSC0FtaW4gTmFzaXJpGDY6BVhlbm9u" | python3 grpc-coder.py --decode --type grpc-web-text | protoscope > out.txt
-```
-
-2. Edit the content of decoded payload
-
-```
-nano out.txt
-2: {"Amin Nasiri Xenon GRPC"}
-3: 54
-7: {""}
-```
-
-3. Encode the new payload
-
-```bash
-protoscope -s out.txt | python3 grpc-coder.py --encode --type grpc-web-text
-```
-
-4. Use output in Burp interceptor:
-
-```
-AAAAADoSFkFtaW4gTmFzaXJpIFhlbm9uIEdSUEMYNjoePHNjcmlwdD5hbGVydChvcmlnaW4pPC9zY3JpcHQ+
-```
-
-### **Manual with gRPC-Web Coder Burp Suite Extension**
-
-You can use gRPC-Web Coder Burp Suite Extension in [gRPC-Web Pentest Suite](https://github.com/nxenon/grpc-pentest-suite) which is easier. You can read the installation and usage instruction in its repo.
-
-## **Analysing gRPC-Web Javascript Files**
-
-There is at least one Javascript file in every gRPC-Web application. You can analyse the file to find new messages, endpoints and services. Try using [gRPC-Scan](https://github.com/nxenon/grpc-pentest-suite) tool.
-
-1. Download the Javascript gRPC-Web File
-2. Scan it with grpc-scan.py:
-
-```bash
-python3 grpc-scan.py --file main.js
-```
-
-3. Analyse output and test the new endpoints and new 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 |
-+--------------+----------------+--------------+
-```
-
-## References
-
-- [Hacking into gRPC-Web Article by Amin Nasiri](https://infosecwriteups.com/hacking-into-grpc-web-a54053757a45)
-- [gRPC-Web Pentest Suite](https://github.com/nxenon/grpc-pentest-suite)
-
-{{#include ../banners/hacktricks-training.md}}
+# Pentesting gRPC-Web
+{{#include ../banners/hacktricks-training.md}}
+## Quick protocol recap and attack surface
+- Transport: 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 you will see:
+ - application/grpc-web (binary framing)
+ - application/grpc-web-text (base64-encoded framing for HTTP/1.1 streaming)
+- Framing: every message is prefixed with a 5‑byte gRPC header (1‑byte flags + 4‑byte length). In gRPC‑Web, trailers (grpc-status, grpc-message, …) are sent inside the body as a special frame: first byte with MSB set (0x80) followed by a length and a HTTP/1.1‑style header block.
+- Common request headers: x-grpc-web: 1, x-user-agent: grpc-web-javascript/…, grpc-timeout, grpc-encoding. Responses expose grpc-status/grpc-message via trailers/body frames and often via Access-Control-Expose-Headers for browsers.
+- Security‑relevant middleware often present:
+ - Envoy grpc_web filter and gRPC‑JSON transcoder (HTTP<->gRPC bridge)
+ - Nginx/APISIX gRPC‑Web plugins
+ - CORS policies on the proxy
+
+What this means for attackers:
+- You can craft requests by hand (binary or base64 text), or let tooling generate/encode them.
+- CORS mistakes on the proxy can allow cross‑site, authenticated gRPC‑Web calls (similar to classic CORS issues).
+- JSON transcoding bridges may unintentionally expose gRPC methods as unauthenticated HTTP endpoints if routes/auth are misconfigured.
+
+## Testing gRPC‑Web from the CLI
+
+### Easiest: buf curl (speaks gRPC‑Web natively)
+
+- List methods via reflection (if enabled):
+
+```bash
+# list methods (uses reflection)
+buf curl --protocol grpcweb https://host.tld --list-methods
+```
+
+- Call a method with JSON input, auto‑handling gRPC‑Web framing and headers:
+
+```bash
+buf curl --protocol grpcweb \
+ -H 'Origin: https://example.com' \
+ -d '{"field":"value"}' \
+ https://host.tld/pkg.svc.v1.Service/Method
+```
+
+- If reflection is disabled, provide a schema/descriptor set with --schema or point to local .proto files. See buf help curl.
+
+### Raw with curl (manual headers + framed body)
+
+For binary mode (application/grpc-web), send a framed payload (5‑byte prefix + protobuf message). For text mode, base64‑encode the framed payload.
+
+```bash
+# 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
+```
+
+Tip: Force base64/text mode with application/grpc-web-text when HTTP/1.1 intermediaries break binary streaming.
+
+### Check CORS behavior (preflight + response)
+
+- Preflight:
+
+```bash
+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'
+```
+
+- A vulnerable setup often reflects arbitrary Origin and sends Access-Control-Allow-Credentials: true, allowing cross‑site authenticated calls. Also check Access-Control-Expose-Headers includes grpc-status, grpc-message (many deployments expose these for client libs).
+
+For generic techniques to abuse CORS, check [CORS - Misconfigurations & Bypass](cors-bypass.md).
+
+## Manipulating gRPC‑Web payloads
+
+gRPC‑Web uses Content-Type: application/grpc-web-text as a base64‑wrapped gRPC frame stream for browser compatibility. You can decode/modify/encode frames to tamper with fields, flip flags, or inject payloads.
+
+Use the [gprc-coder](https://github.com/nxenon/grpc-pentest-suite) tool (and its Burp extension) to speed up round‑trips.
+
+### Manual with gGRPC Coder Tool
+
+1. Decode the payload:
+
+```bash
+echo "AAAAABYSC0FtaW4gTmFzaXJpGDY6BVhlbm9u" | python3 grpc-coder.py --decode --type grpc-web-text | protoscope > out.txt
+```
+
+2. Edit the content of decoded payload
+
+```
+nano out.txt
+2: {"Amin Nasiri Xenon GRPC"}
+3: 54
+7: {""}
+```
+
+3. Encode the new payload
+
+```bash
+protoscope -s out.txt | python3 grpc-coder.py --encode --type grpc-web-text
+```
+
+4. Use output in Burp interceptor:
+
+```
+AAAAADoSFkFtaW4gTmFzaXJpIFhlbm9uIEdSUEMYNjoePHNjcmlwdD5hbGVydChvcmlnaW4pPC9zY3JpcHQ+
+```
+
+### Manual with gRPC‑Web Coder Burp Suite Extension
+
+You can use gRPC‑Web Coder Burp Suite Extension in [gRPC‑Web Pentest Suite](https://github.com/nxenon/grpc-pentest-suite) which is easier. You can read the installation and usage instruction in its repo.
+
+## Analysing gRPC‑Web JavaScript files
+
+Web apps using gRPC‑Web ship at least one generated JS/TS bundle. Reverse them to extract services, methods, and message shapes.
+
+- Try using [gRPC-Scan](https://github.com/nxenon/grpc-pentest-suite) to parse bundles.
+- Look for method paths like /./, message field numbers/types, and custom interceptors that add auth headers.
+
+1. Download the JavaScript gRPC‑Web file
+2. Scan it with grpc-scan.py:
+
+```bash
+python3 grpc-scan.py --file main.js
+```
+
+3. Analyse output and test the new endpoints and new 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 |
++--------------+----------------+--------------+
+```
+
+## Bridging and JSON transcoding gotchas
+
+Many deployments put an Envoy (or similar) proxy in front of the gRPC server:
+
+- grpc_web filter translates HTTP/1.1 POSTs into HTTP/2 gRPC.
+- gRPC‑JSON Transcoder exposes gRPC methods as HTTP JSON endpoints when .proto options (google.api.http) are present.
+
+From a pentesting perspective:
+- Try direct HTTP JSON calls to /./ with application/json when a transcoder is enabled (auth/route mismatches are common):
+
+```bash
+curl -i https://host.tld/pkg.svc.v1.Service/Method \
+ -H 'Content-Type: application/json' \
+ -d '{"field":"value"}'
+```
+
+- Review whether unknown methods/parameters are rejected or passed through. Some configs forward unmatched paths upstream, occasionally bypassing auth or request validation.
+- Observe x-envoy-original-path and related headers added by proxies. Upstreams that trust these may be abusable if the proxy fails to sanitize them.
+
+## References
+
+- [Hacking into gRPC‑Web Article by Amin Nasiri](https://infosecwriteups.com/hacking-into-grpc-web-a54053757a45)
+- [gRPC‑Web Pentest Suite](https://github.com/nxenon/grpc-pentest-suite)
+- [gRPC‑Web protocol notes (PROTOCOL‑WEB.md)](https://chromium.googlesource.com/external/github.com/grpc/grpc/%2B/v1.16.1/doc/PROTOCOL-WEB.md)
+
+{{#include ../banners/hacktricks-training.md}}