Skip to content

fix: gRPC detection can now connect to real (h2c) gRPC servers#77

Merged
GovindarajanL merged 1 commit into
OWASP:mainfrom
GovindarajanL:fix/72-grpc-h2c-detection
Jul 25, 2026
Merged

fix: gRPC detection can now connect to real (h2c) gRPC servers#77
GovindarajanL merged 1 commit into
OWASP:mainfrom
GovindarajanL:fix/72-grpc-h2c-detection

Conversation

@GovindarajanL

Copy link
Copy Markdown
Collaborator

Fixes #72

Summary

GrpcEndpointDetectionTestCase probed for gRPC services over the shared HttpClient, which wraps a standard OkHttp client. gRPC's wire protocol is HTTP/2-only, and OkHttp never attempts HTTP/2 over a plain http:// URL by default (there's no ALPN negotiation without TLS) — it silently falls back to HTTP/1.1, which a gRPC server cannot understand at all. The probe request fails at the transport layer before there's ever a response to inspect.

Reproduction

Built and ran gRPC Goat labs 001 (server reflection enabled) and 002 (plaintext gRPC), both confirmed live via docker logs. Scanning both produced 0 findings on both, including lab001 — the "reflection enabled" scenario this test case is specifically meant to catch.

Confirmed the transport-level cause by hand:

$ curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8001/
000   # plain HTTP/1.1 — connection never completes

$ curl -s -o /dev/null -w "%{http_code}" --http2-prior-knowledge http://127.0.0.1:8001/
415   # real HTTP/2 connection succeeds — server is genuinely reachable

Fix

Adds HttpClient.postH2c(), which routes cleartext (http://) targets through a dedicated client configured for Protocol.H2_PRIOR_KNOWLEDGE. https:// targets are unaffected and continue through the standard client, which already negotiates HTTP/2 via ALPN when the server supports it — no change to any other test case's behavior.

Verification

  • Re-ran against both gRPC Goat labs after the fix: 2/2 detection, up from 0/2. Both now report the gRPC endpoint detection (INFO) and "gRPC Server Reflection Enabled" (MEDIUM).
  • Existing unit tests updated to mock postH2c instead of postWithStatus; all still pass.
  • Full suite passes (241 tests).

Test plan

  • mvn test passes
  • Re-scanned gRPC Goat lab001 and lab002 with the fixed jar — both correctly detected, including reflection

GrpcEndpointDetectionTestCase probed for gRPC services over the shared
HttpClient, which wraps a standard OkHttp client. gRPC's wire protocol
is HTTP/2-only, and OkHttp never attempts HTTP/2 over a plain "http://"
URL by default (there's no ALPN negotiation without TLS) -- it silently
falls back to HTTP/1.1, which a gRPC server cannot understand at all.
The probe request fails at the transport layer before there's ever a
response to inspect.

Reproduced against gRPC Goat labs 001 (server reflection enabled) and
002 (plaintext gRPC), both confirmed live via docker logs: 0 findings on
both. Confirmed the transport-level cause by hand -- a plain HTTP/1.1
request never connects (curl: 000), while --http2-prior-knowledge
succeeds (curl: 415, real HTTP/2 response).

Adds HttpClient.postH2c(), which routes cleartext ("http://") targets
through a dedicated client configured for Protocol.H2_PRIOR_KNOWLEDGE.
"https://" targets are unaffected and continue through the standard
client, which already negotiates HTTP/2 via ALPN when supported.

Fixes OWASP#72

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@GovindarajanL
GovindarajanL merged commit 064fdcf into OWASP:main Jul 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gRPC detection cannot connect to real gRPC servers — 0% detection rate against live targets

1 participant