-
Bug
-
Resolution: Done
-
Major
-
None
-
None
-
2
-
False
-
-
False
-
-
-
OAPE Sprint 279
-
1
OpenShift SCC Authorization Bypass Bug
Summary: OpenShift SCC admission controller bypasses service account authorization when pod security profile matches an SCC
Component: OpenShift SCC Admission Controller
Version: OpenShift 4.20.0
Severity: HIGH
Status: New
Description
Expected Behavior:
- SCC users: field defines which service accounts can use that SCC
- Pods using unauthorized service accounts should NOT get that SCC
- Only authorized service accounts should be able to use the SCC
Actual Behavior:
- When a pod's security profile matches an SCC perfectly, OpenShift skips the service account authorization check
- Pod gets the SCC even if using an unauthorized service account
- Authorization is completely bypassed
Impact:
- Authorization bypass - violates principle of least privilege
- Unauthorized pods gain privileged mode access
- SCC security restrictions still enforced (mitigating factor)
Simple Explanation
Think of it like a building access card system:
What Should Happen:
- Security checks your ID badge (service account)
- If your badge has access, they check if you meet dress code requirements (security profile)
- Both must match to enter
What Actually Happens (The Bug):
- Security sees you're wearing the correct uniform (security profile matches)
- They let you in WITHOUT checking your badge
- Anyone wearing the right clothes can enter, regardless of authorization!
In OpenShift Terms:
The SCC says "Only the spire-spiffe-csi-driver service account can use me"
But ANY pod requesting privileged: true with capabilities.drop: ["ALL"] gets access
The admission controller is checking the "security outfit" but not the "ID badge"
Reproduction Steps
Step 1: Check Who is Authorized
Run this command to see who is allowed to use the SCC:
oc get scc spire-spiffe-csi-driver -o jsonpath='\{.users}'
Expected Output:
["system:serviceaccount:zero-trust-workload-identity-manager:spire-spiffe-csi-driver"]
What This Means: ✓ Only spire-spiffe-csi-driver service account is authorized
Step 2: Create a Pod with the WRONG Service Account
Now create a pod that uses a different service account (default) but has a security profile that matches the SCC:
cat <<EOF | oc apply -f - apiVersion: v1 kind: Pod metadata: name: test-violation-sa namespace: zero-trust-workload-identity-manager spec: serviceAccountName: default containers: - name: test image: registry.access.redhat.com/ubi8/ubi-minimal:latest command: ["sleep", "3600"] securityContext: privileged: true capabilities: drop: ["ALL"] EOF
Note: This pod uses:
- ✗ Service Account: default (NOT authorized - not in the list from Step 1)
- ✓ Security Profile: privileged: true + capabilities.drop: ["ALL"] (matches SCC requirements)
Step 3: Wait for Pod to Start
sleep 20
During this time, OpenShift's SCC admission controller decides which SCC to assign to the pod.
Step 4: Check Which SCC Was Assigned (THE BUG!)
oc get pod test-violation-sa -n zero-trust-workload-identity-manager \
-o jsonpath='\{.metadata.annotations.openshift\.io/scc}'
Expected Output:
anyuid
OR
privileged
(Any SCC that the default service account is authorized to use)
Actual Output (BUG):
spire-spiffe-csi-driver
✗ BUG CONFIRMED: Pod got spire-spiffe-csi-driver SCC even though it's using default service account which is NOT authorized!
Step 5: Show the Authorization Mismatch
Run this to see the clear mismatch:
echo "=== Who is AUTHORIZED? ===" oc get scc spire-spiffe-csi-driver -o jsonpath='\{.users}' echo "" echo "" echo "=== What did our TEST POD get? ===" oc get pod test-violation-sa -n zero-trust-workload-identity-manager \ -o custom-columns=NAME:.metadata.name,SA:.spec.serviceAccountName,SCC:.metadata.annotations.openshift\\.io/scc
Output:
=== Who is AUTHORIZED? === ["system:serviceaccount:zero-trust-workload-identity-manager:spire-spiffe-csi-driver"] === What did our TEST POD get? === NAME SA SCC test-violation-sa default spire-spiffe-csi-driver ↑ ↑ WRONG! SHOULD NOT HAVE ACCESS!
Actual Test Results from Real Cluster
Authorized User (from SCC): system:serviceaccount:zero-trust-workload-identity-manager:spire-spiffe-csi-driver Test Pod (Using Wrong SA): Service Account: default Assigned SCC: spire-spiffe-csi-driver ← BUG! This should NOT happen! Status: Running Real CSI Driver Pods (For Comparison): spire-spiffe-csi-driver-c7jnw → SA: spire-spiffe-csi-driver, SCC: spire-spiffe-csi-driver ✓ spire-spiffe-csi-driver-cn6f6 → SA: spire-spiffe-csi-driver, SCC: spire-spiffe-csi-driver ✓ spire-spiffe-csi-driver-xkvlv → SA: spire-spiffe-csi-driver, SCC: spire-spiffe-csi-driver ✓
Notice: The real CSI driver pods use the correct service account. Our test pod uses the wrong service account but still got the same SCC!
Why This is a Bug (Root Cause)
Current (Buggy) Flow:
Step 1: Find SCCs that match the pod's security profile Step 2: Select the best matching SCC Step 3: Assign it to the pod ↑ Authorization check is SKIPPED!
Correct Flow (How it Should Work):
Step 1: Find SCCs the service account is AUTHORIZED to use Step 2: From authorized SCCs, find ones that match security profile Step 3: Select the best match and assign ↑ Authorization checked FIRST!
The Problem: When a pod's security profile perfectly matches an SCC, the admission controller prioritizes the profile match and skips the authorization check entirely.
Visual Comparison
Legitimate Pod (Correct):
Pod: spire-spiffe-csi-driver-c7jnw ├─ Service Account: spire-spiffe-csi-driver ✓ (Authorized) ├─ Security Profile: privileged + caps dropped ✓ (Matches) └─ Result: Gets spire-spiffe-csi-driver SCC ✓ CORRECT
Test Pod (Bug):
Pod: test-violation-sa ├─ Service Account: default ✗ (NOT Authorized) ├─ Security Profile: privileged + caps dropped ✓ (Matches) └─ Result: Gets spire-spiffe-csi-driver SCC ✗ BUG!
The bug: OpenShift checks the security profile (✓) but ignores the service account authorization (✗)
Cleanup After Testing
oc delete pod test-violation-sa -n zero-trust-workload-identity-manager
- account is impacted by
-
SPIRE-253 Premarge testing => Restrict SCC for spiffe-csi-driver
-
- Closed
-