Skip to content
Security
Skill

/attacking-grpc-protobuf

Test gRPC and Protocol Buffers services — recovering .proto definitions from server reflection or compiled descriptors, calling methods with grpcurl and grpcui, intercepting HTTP/2 and gRPC-Web traffic, and fuzzing unknown message schemas with protobuf-inspector. Use when a

BOOST
From plugin
secskills
17094 skills
Install
$ npx -y skills add trilwu/secskills --skill attacking-grpc-protobuf --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/attacking-grpc-protobuf

Context preview

The summary Claude sees to decide when to auto-load this skill.

Test gRPC and Protocol Buffers services — recovering .proto definitions from server reflection or compiled descriptors, calling methods with grpcurl and grpcui, intercepting HTTP/2 and gRPC-Web traffic, and fuzzing unknown message schemas with protobuf-inspector. Use when a

SKILL.md

attacking-grpc-protobuf.SKILL.md
name: attacking-grpc-protobuf
description: Test gRPC and Protocol Buffers services — recovering .proto definitions from server reflection or compiled descriptors, calling methods with grpcurl and grpcui, intercepting HTTP/2 and gRPC-Web traffic, and fuzzing unknown message schemas with protobuf-inspector. Use when a target speaks gRPC, HTTP/2 with application/grpc, or when a request body is opaque binary protobuf rather than JSON.
verified: 2026-07-27

Attacking gRPC and Protobuf Services

gRPC breaks the tooling assumption that a request is readable text over HTTP/1.1. Burp shows a binary blob or nothing at all, and without the schema you cannot even name the methods. Recover the schema and it becomes an ordinary API test — with the twist that gRPC services are frequently internal services newly exposed, which means their authorization is often weaker than the REST API in front of them.

When to Use

  • Traffic uses HTTP/2 with `content-type: application/grpc`
  • A request or response body is opaque binary with no JSON structure
  • The app is a mobile or desktop client talking to a backend over protobuf
  • You find `.proto` files, `*_pb2.py`, `*.pb.go`, or `grpc` in a codebase
  • `application/grpc-web` or `application/grpc-web+proto` appears in a browser app

When NOT to Use

  • **REST or GraphQL** — use `testing-apis`
  • **The proxy cannot see the traffic at all** on mobile — use

`bypassing-mobile-pinning`; gRPC clients often ignore system proxy settings

  • **Source code is available** — use `auditing-code-for-vulnerabilities`, and

read the `.proto` files directly

  • **Binary protocol that is not protobuf** — use `analyzing-binaries`

Recover the Schema

Everything depends on this. Four routes, in order of cost.

**1. Server reflection.** Many services ship it enabled, often unintentionally.

grpcurl -plaintext target:50051 list
grpcurl -plaintext target:50051 list package.ServiceName
grpcurl -plaintext target:50051 describe package.ServiceName.MethodName
grpcurl -plaintext target:50051 describe package.RequestMessage

# TLS
grpcurl target:443 list
grpcurl -insecure target:443 list          # self-signed / proxy in path

Reflection enabled on an internet-facing service is itself worth reporting — it is the gRPC equivalent of GraphQL introspection in production.

**2. Descriptors compiled into a client.** Protobuf embeds a serialized `FileDescriptorProto` in generated code, so the schema is recoverable from any client binary.

# Mobile/desktop client: find and extract descriptor blobs
rg -a -o 'google/protobuf/descriptor.proto|\.proto' target_binary | head
# protobuf-inspector and protod can reconstruct .proto from embedded descriptors
protod target_binary -o ./protos

# JS/web clients: the descriptor is usually in the bundle as base64 or an array
rg -n 'grpc-web|serializeBinary|deserializeBinary' bundle.js | head

**3. From the app's source or artifacts.** `.proto` files in a repo, a Swagger gateway config, or generated stubs in a package.

**4. Field-by-field inference.** When you have neither, decode the wire format directly. Protobuf is self-describing enough to recover structure without the schema:

protoc --decode_raw < message.bin
protobuf-inspector < message.bin
# Output: field numbers, wire types, and values — enough to fuzz and to
# recognize strings, nested messages, and integers

You lose field *names* but keep field *numbers*, which is all the wire format needs. That is sufficient to modify values and to add fields the client never sends.

Calling Methods

# With reflection
grpcurl -plaintext -d '{"user_id": 1}' target:50051 package.Service/GetUser

# With a local .proto
grpcurl -import-path ./protos -proto api.proto \
        -d '{"user_id": 1}' target:50051 package.Service/GetUser

# Interactive browser UI, good for exploring
grpcui -plaintext target:50051

# Headers, including auth
grpcurl -H 'authorization: Bearer eyJ...' -plaintext target:50051 package.Service/List

For streaming methods, `grpcurl` accepts newline-delimited JSON on stdin for client streaming, and prints each message for server streaming. Streaming endpoints are frequently less-tested than unary ones and worth specific attention.

Intercepting Traffic

# mitmproxy speaks HTTP/2 and can decode gRPC with a schema
mitmproxy --mode regular --set http2=true
#   the gRPC content-view renders protobuf; supply .proto for field names

# Burp: enable HTTP/2, and use a protobuf decoder extension
#   without one, you see length-prefixed binary frames

# gRPC-Web is easier — it rides HTTP/1.1 with base64 or binary framing,
# so a normal proxy sees the requests

**gRPC framing**: each message is a 1-byte compression flag, a 4-byte big-endian length, then the protobuf bytes. When a decoder shows nothing, strip those five bytes before feeding the payload to `protoc --decode_raw`.

python3 -c "
import sys
d = sys.stdin.buffer.read()
sys.stdout.buffer.write(d[5:])" < frame.bin | protoc --decode_raw

Clients that ignore the system proxy need a network-layer redirect; see `bypassing-mobile-pinning`.

What to Test

The bug classes are the same as any API, but gRPC changes where they hide.

**Authorization per method.** gRPC has no path-based access control, so a reverse proxy or WAF that filters `/admin/*` does nothing. Each method must check authorization itself — enumerate every method from reflection and call each one with a low-privilege token.

for m in $(grpcurl -plaintext target:50051 list package.Service | tail -n +2); do
  echo "== $m"; grpcurl -H "authorization: Bearer $LOW_PRIV" -plaintext -d '{}' target:50051 "$m" 2>&1 | head -3
done

**Internal services exposed.** gRPC is a service-mesh protocol, so many services were written assuming only other services would call them. If you can reach one directly, expect no authentication at all — and expect it to trust identity claims passed as ordinary request fields

Read more
Ships withsecskills

**Security skills for Claude Code that encode the judgment professionals bring, not another wrapper around a scanner.** Offense, defense, and the reverse-engineering and code-audit core both sides share. Every skill is fact-checked against primary sources.

Get the whole plugin

Other skills on secskills.