Operations 16 min read

Kubernetes Security Audit Reveals 23 Critical Vulnerabilities: From Anonymous API Access to cluster-admin Abuse

A detailed case study of a Kubernetes cluster security audit uncovering 23 high-severity vulnerabilities including anonymous API server access, hostPath mounting of /etc, and a test ServiceAccount with cluster-admin privileges, plus the remediation process and organizational challenges.

ITPUB
ITPUB
ITPUB
Kubernetes Security Audit Reveals 23 Critical Vulnerabilities: From Anonymous API Access to cluster-admin Abuse

Background: Why a Security Audit After Performance Profiling

The author previously used eBPF for a performance health check that revealed five issues invisible to traditional monitoring. However, eBPF observes kernel behavior but cannot detect configuration-layer problems such as excessive RBAC permissions or anonymous API server access. This gap prompted a full security audit using kube-bench, checkov, and manual review over two weeks.

Vulnerability Distribution by Attack Scenario

The 23 high-severity findings were categorized by potential impact rather than CVE numbers:

If an attacker reaches the internal network (7): privileged containers, hostPath mounts, hostNetwork

If an attacker compromises a Pod (6): over-permissive ServiceAccounts, accessible secrets

If an attacker accesses the API Server (4): unauthenticated access, anonymous user enabled

If the container image is compromised (4): base image vulnerabilities, latest tag usage, root user

If network segmentation is absent (2): no NetworkPolicy, cross-namespace access

The term "high-severity" includes both known CVEs and configuration risks (privileged containers, excessive permissions), rated by actual harm potential.

The oldest vulnerability dated back to cluster initialization several years earlier.

Three Most Alarming Findings

1. API Server Anonymous Access Enabled

Discovery: --anonymous-auth=true in kube-apiserver startup parameters. This allowed anyone with network access to the API server endpoint to run commands like kubectl --server=https://api-server:6443 get pods -A or

curl -k https://api-server:6443/api/v1/namespaces/default/pods

without certificates or tokens.

Further investigation showed the anonymous user (system:anonymous) was bound to a custom cluster-role-viewer role granting read access to all resources across all namespaces — Pods, Services, ConfigMaps, Secrets, and RBAC configuration.

Root cause: Added during cluster initialization for "convenience of internal systems" but no one remembered which system or assessed the risk.

Fix: Set --anonymous-auth=false and remove all system:anonymous role bindings.

2. Pod Mounting Host's /etc Directory

A "data sync service" Pod used hostPath to mount the host's /etc directory:

volumes:
- name: host-etc
  hostPath:
    path: /etc
    type: Directory
volumeMounts:
- name: host-etc
  mountPath: /host-etc

Risk: The Pod could read /etc/shadow (password hashes), /etc/ssh/sshd_config, modify /etc/hosts (DNS hijacking), and modify /etc/crontab (persistence via cron). Combined with the image using latest tag and no resource limits, compromise of this Pod equated to host root access.

Business context: A legacy cron job syncing config files every 24 hours.

Fix: Remove hostPath mount; use ConfigMap/Secret for configuration; if host file access is mandatory, use read-only, specific-file mounts with minimal capabilities.

3. ServiceAccount with cluster-admin Bound to a Test Pod

A ServiceAccount named data-sync-sa had cluster-admin ClusterRole binding — the highest privilege in Kubernetes, allowing creation/deletion of any resource, access to all Secrets, namespace management, and RBAC modification.

The account was used by a temporary test data-generation tool in a test environment.

Attack scenario: If an attacker gains shell access to this Pod (via app vulnerability, image poisoning, etc.), they can:

# Read all secrets
kubectl get secrets -A
# Create backdoor pod in kube-system
kubectl run backdoor --image=attacker-image -n kube-system
# Modify cluster config
kubectl edit configmap -n kube-system some-config
# Delete entire cluster
kubectl delete namespace --all

Root cause: Developers encountered permission issues during initial deployment and granted cluster-admin to "get it running first," then never revisited.

Fix: (1) Create a minimal Role with only required permissions; (2) Remove cluster-admin binding; (3) Establish periodic ServiceAccount permission audits.

Other Notable Findings

Privileged Containers (5 instances)

Five Pods ran with privileged: true, granting full device access, kernel parameter modification, and module loading. One monitoring collector needed host /proc and /sys access but only required specific capabilities ( SYS_ADMIN, NET_ADMIN) rather than full privilege.

Fix: Replace privileged: true with precise capabilities.

Images Using latest Tag (12 services)

Using latest means each deploy may pull a different image version. If the registry is compromised, a malicious image could be deployed automatically. Also makes version traceability impossible.

Fix: Pin all images to explicit version tags; ban latest.

No NetworkPolicy

Zero NetworkPolicy resources existed. Any Pod could reach any other Pod across namespaces. A compromised Pod could scan the cluster network, access databases, and reach internal services.

Fix: Implement default-deny policies for critical namespaces at minimum.

Remediation Negotiations: The Human Factor

vs. Developers

Developers resisted removing privileged mode claiming "it won't run without it." When pressed for specific requirements, they didn't know. The author spent half a day analyzing the actual need — only NET_BIND_SERVICE (binding port 80) was required. Changing from privileged: true to a single capability reduced attack surface by ~99%.

vs. Security Team

Security demanded all 23 vulnerabilities be fixed as P0. The author pushed back on feasibility and business impact. They eventually agreed on a risk-based prioritization using likelihood × impact :

P0 (fix within 1 week): API Server anonymous access, cluster-admin binding, hostPath /etc mount (3 items)

P1 (fix within 1 month): Privileged containers, image vulnerabilities (9 items)

P2 (fix within 3 months): NetworkPolicy, latest tags (11 items)

vs. Management

Management asked for quantified attack probability and remediation cost. The author explained probability cannot be quantified but impact is total cluster compromise. Management required a timeline and risk assessment before approving changes.

Security remediation is never purely a technical problem — it's a risk decision problem.

Lessons Learned

Security vulnerabilities are silent debt. None of the 23 issues were newly introduced; they accumulated unnoticed. Unlike performance issues that surface actively, security flaws lie dormant until exploited. Not auditing doesn't mean no vulnerabilities — it means you don't know them.

Least privilege is not a slogan. cluster-admin, privileged containers, hostPath mounts all stemmed from "convenience." Spending 10 minutes upfront to define minimal required permissions prevents massive later risk. "Get it running first" is the most dangerous mindset.

Security and convenience are inherently in tension. Anonymous auth for "easy internal calls," privileged mode for "won't run otherwise," latest tag for "avoiding version bumps." Every vulnerability has a convenience justification. Security is fundamentally trading convenience for safety.

Security auditing must be continuous. Post-audit, the author integrated checks into CI/CD:

Image scanning on every build for known CVEs

YAML linting with kube-score or checkov

Monthly RBAC permission audits

Security is not a one-off project but an ongoing process.

Closing Reflection

The audit shifted the author's view: Kubernetes security is not solely the security team's responsibility — it is a core operational duty alongside stability. Unstable systems draw user complaints; insecure systems cause company-ending incidents. The 23 vulnerabilities took two months to remediate, but new services, config changes, and CVEs ensure the work continues. The goal is keeping risk controllable.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KubernetesContainer SecurityRBACDevSecOpsAPI ServerhostPathNetworkPolicySecurity Audit
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.