bitwalker / bitwalker/libcluster
CWE-295: TLS verification disabled in K8s strategy fallback — verify_none when ca.crt missing, Bearer token exposed
- Dominant language
- Elixir
- Stars
- 2.2k
- Forks
- 201
- PR merge metrics
- No merged PRs in 30d
Description
### Summary
The Kubernetes clustering strategy's `get_ssl_opts/1` function falls back to `verify: :verify_none` when the service account's `ca.crt` file is missing. This means K8s API Bearer tokens are transmitted over TLS connections that accept any certificate.
### Vulnerable Code (`lib/strategy/kubernetes.ex:323-337`)
```elixir
defp get_ssl_opts(service_account_path) do
path = Path.join(service_account_path, "ca.crt")
case File.exists?(path) do
true -> [verify: :verify_peer, cacertfile: String.to_charlist(path)]
false -> [verify: :verify_none] # ← DANGEROUS FALLBACK
end
end
```
### Credential Flow
- `verify: :verify_none` is passed as SSL options to `:httpc.request()`
- The K8s service account Bearer token is sent via `Authorization: Bearer {token}` header
- All K8s API responses (pod lists, ConfigMaps, Secrets) transit over unverified TLS
### Impact
MITM attacker can capture the K8s service account token, gaining API access within the cluster — pod enumeration, ConfigMap/Secret access, lateral movement.
### Fix
Never fall back to `verify_none`. Use system CA store instead:
```elixir
false -> [verify: :verify_peer] # Use system CA, don't disable verification
```
### Severity
CVSS 7.4 (HIGH) — CWE-295: Improper Certificate Validation
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in lib/strategy/kubernetes.ex:323-337 at get_ssl_opts/1 and trace how its returned options reach the Kubernetes HTTP request. Ensure the missing-ca.crt path no longer disables certificate verification, then run the relevant project tests to confirm the fallback preserves peer verification.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- elixir, kubernetes
- Domain
- authentication, backend, security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100