# Grpc Web Pentest

> Pentest gRPC-Web services and endpoints. Use this skill whenever the user mentions gRPC-Web, gRPC over HTTP, protobuf services, Envoy proxies, or wants to test/audit gRPC-Web APIs. Trigger for any gRPC-Web reconnaissance, payload manipulation, CORS testing, or JavaScript bundle analysis tasks.

- Skill: `abelrguezr/grpc-web-pentest` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/grpc-web-pentest`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/grpc-web-pentest/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/grpc-web-pentest

---


# gRPC-Web Pentesting

A skill for security testing gRPC-Web services, including reconnaissance, payload manipulation, and vulnerability discovery.

## When to use this skill

Use this skill when:
- Testing gRPC-Web endpoints (application/grpc-web or application/grpc-web-text content types)
- Analyzing JavaScript bundles for gRPC service definitions
- Testing CORS configurations on gRPC-Web proxies
- Manipulating gRPC-Web payloads for fuzzing or exploitation
- Auditing Envoy/APISIX gRPC-Web proxy configurations
- Investigating gRPC-JSON transcoder misconfigurations

## Quick Protocol Reference

### Transport & Framing

- **Transport**: HTTP/1.1 or HTTP/2 via proxy (Envoy, APISIX, grpcwebproxy)
- **Supported calls**: Unary and server-streaming only
- **Content-Types**:
  - `application/grpc-web` - Binary framing
  - `application/grpc-web-text` - Base64-encoded framing for HTTP/1.1

### Message Structure

Every gRPC-Web message has a 5-byte header:
- **Byte 0**: Flags (0x00 = uncompressed, 0x01 = compressed)
- **Bytes 1-4**: Message length (big-endian)
- **Bytes 5+**: Protobuf message payload

Trailers are sent as a special frame with MSB set (0x80) followed by HTTP/1.1-style headers.

### Common Headers

**Request**:
- `x-grpc-web: 1`
- `x-user-agent: grpc-web-javascript/0.1`
- `grpc-timeout: <duration>`
- `grpc-encoding: <compression>`

**Response** (often exposed via `Access-Control-Expose-Headers`):
- `grpc-status`
- `grpc-message`

## Reconnaissance

### 1. List Available Methods (if reflection enabled)

```bash
buf curl --protocol grpcweb https://target.tld --list-methods
```

### 2. Analyze JavaScript Bundles

Download and scan JS files to extract service definitions:

```bash
# Download the bundle
wget https://target.tld/main.js

# Scan for gRPC endpoints and message schemas
python3 scripts/grpc-scan.py --file main.js
```

This reveals:
- Service paths (e.g., `/pkg.svc.v1.Service/Method`)
- Message field numbers and types
- Custom interceptors and auth headers

### 3. Test CORS Configuration

Check for CORS misconfigurations that allow cross-site authenticated calls:

```bash
curl -i -X OPTIONS https://target.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'
```

**Vulnerable indicators**:
- `Access-Control-Allow-Origin: *` or reflects arbitrary Origin
- `Access-Control-Allow-Credentials: true` with permissive origin
- `Access-Control-Expose-Headers` includes `grpc-status`, `grpc-message`

## Making Requests

### Method 1: buf curl (Recommended)

```bash
# Call a method with JSON input
buf curl --protocol grpcweb \
  -H 'Origin: https://example.com' \
  -d '{"field":"value"}' \
  https://target.tld/pkg.svc.v1.Service/Method
```

### Method 2: Raw curl with Manual Framing

For binary mode:

```bash
# Create framed payload and send
echo -n 'YOUR_PROTOBUF_BYTES' | python3 scripts/grpc-coder.py --encode --type grpc-web | \
  tee body.bin

curl -i https://target.tld/pkg.svc.v1.Service/Method \
  -H 'Content-Type: application/grpc-web' \
  -H 'X-Grpc-Web: 1' \
  -H 'X-User-Agent: grpc-web-javascript/0.1' \
  --data-binary @body.bin
```

For text mode (base64, better for HTTP/1.1):

```bash
echo -n 'YOUR_PROTOBUF_BYTES' | python3 scripts/grpc-scan.py --encode --type grpc-web-text | \
  tee body.b64

curl -i https://target.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
```

## Payload Manipulation

### Decode, Modify, Re-encode

```bash
# Decode a gRPC-Web-text payload
echo "AAAAABYSC0FtaW4gTmFzaXJpGDY6BVhlbm9u" | \
  python3 scripts/grpc-coder.py --decode --type grpc-web-text

# Edit the decoded protobuf (use protoscope or similar)
nano decoded.txt

# Re-encode with modifications
cat decoded.txt | python3 scripts/grpc-coder.py --encode --type grpc-web-text
```

### Common Attack Vectors

1. **Field injection**: Add unexpected fields to test validation
2. **Type confusion**: Change field types (int to string, etc.)
3. **Overflow**: Send oversized messages to test rate limiting
4. **XSS via trailers**: Inject `<script>` tags in string fields
5. **Auth bypass**: Remove or modify auth-related fields

## Proxy & Transcoder Testing

### Test gRPC-JSON Transcoder

Many deployments expose gRPC methods as HTTP JSON endpoints:

```bash
curl -i https://target.tld/pkg.svc.v1.Service/Method \
  -H 'Content-Type: application/json' \
  -d '{"field":"value"}'
```

**What to check**:
- Does it work without gRPC-Web headers?
- Are auth requirements different?
- Do unknown parameters get passed through?

### Test Proxy Header Injection

```bash
curl -i https://target.tld/pkg.svc.v1.Service/Method \
  -H 'x-envoy-original-path: /admin/secret' \
  -H 'Content-Type: application/grpc-web-text' \
  -d 'BASE64_PAYLOAD'
```

Some upstreams trust `x-envoy-original-path` and may bypass validation.

## Common Vulnerabilities

| Vulnerability | Description | Detection |
|--------------|-------------|------------|
| CORS misconfiguration | Allows cross-site authenticated calls | OPTIONS preflight test |
| Unauthenticated transcoder | JSON endpoint bypasses gRPC auth | Try application/json without auth |
| Reflected headers | Proxy reflects malicious headers | Check x-envoy-original-path |
| Missing input validation | Protobuf fields not validated | Fuzz field values/types |
| Trailers exposure | Sensitive data in grpc-message | Check Access-Control-Expose-Headers |

## Tooling

### Built-in Scripts

- `scripts/grpc-coder.py` - Encode/decode gRPC-Web frames
- `scripts/grpc-scan.py` - Analyze JS bundles for gRPC definitions

### External Tools

- [grpc-pentest-suite](https://github.com/nxenon/grpc-pentest-suite) - Full pentest toolkit
- `buf curl` - Native gRPC-Web client
- `protoscope` - Protobuf message editor

## Workflow Checklist

1. [ ] Identify gRPC-Web endpoints (JS bundle analysis, network monitoring)
2. [ ] Test CORS configuration (OPTIONS preflight)
3. [ ] List available methods (reflection or JS analysis)
4. [ ] Make baseline requests (buf curl or raw curl)
5. [ ] Test gRPC-JSON transcoder endpoints
6. [ ] Manipulate payloads (field injection, type confusion)
7. [ ] Test proxy header injection
8. [ ] Check for auth bypasses
9. [ ] Document findings

## References

- [gRPC-Web Protocol](https://chromium.googlesource.com/external/github.com/grpc/grpc/+v1.16.1/doc/PROTOCOL-WEB.md)
- [grpc-pentest-suite](https://github.com/nxenon/grpc-pentest-suite)
- [Hacking into gRPC-Web](https://infosecwriteups.com/hacking-into-grpc-web-a54053757a45)

