OWASP Kubernetes Top 10とは

OWASP Kubernetes Top 10は、Kubernetes環墁E��おける最も重大なセキュリチE��リスクを特定してぁE��す、EubernetesはコンチE��オーケストレーションの事実上�E標準となってぁE��すが、その柔軟性と褁E��性は数多くのセキュリチE��課題をもたらします。本ガイドでは、ワークロード�E設定ミス、RBACの問題、シークレチE��管琁E��ネチE��ワーク刁E��などを網羁E��ます、E/p>

1�E�⃣ K01 - 安�EでなぁE��ークロード設宁E/h2> Critical

概要E/h3>

安�EでなぁE��ークロード設定�E、KubernetesセキュリチE��における最も一般皁E��問題です。rootとして実行されるコンチE��、E��剰な権限、書き込み可能なファイルシスチE��、リソース制限なし�E設定�E重大な攻撁E��を生み出します。デフォルト設定�E多くの場合安�Eではなく、�E示皁E��強化する忁E��があります、E/p>

リスク

root権限とホストアクセスを持つ侵害されたコンチE��は、コンチE��サンド�EチE��スから脱出し、�EストファイルシスチE��にアクセスし、他�Eワークロードに侵入できます。設定ミスのあるPodからの権限�E格は、クラスタ全体�E侵害につながる可能性があります、E/p>

脁E��なコード侁E/h3>
YAML (Kubernetes Pod) ❁EBad
apiVersion: v1
kind: Pod
metadata:
  name: insecure-app
spec:
  containers:
  - name: app
    image: myapp:latest          # Mutable tag!
    securityContext:
      privileged: true            # Full host access!
      runAsUser: 0                # Running as root!
    volumeMounts:
    - mountPath: /host
      name: host-fs
  volumes:
  - name: host-fs
    hostPath:
      path: /                    # Entire host filesystem!

安�Eなコード侁E/h3>
YAML (Kubernetes Pod) ✁EGood
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: myapp@sha256:abc123...  # Immutable digest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      runAsUser: 1000
      capabilities:
        drop: ["ALL"]
    resources:
      limits:
        cpu: "500m"
        memory: "256Mi"
      requests:
        cpu: "100m"
        memory: "128Mi"

対策チェチE��リスチE/h3>

2�E�⃣ K02 - 過度に寛容な認可設宁E/h2> Critical

概要E/h3>

KubernetesのRBAC(ロールベ�Eスアクセス制御)は強力ですが褁E��です。過度に寛容なロール、特にcluster-adminバインチE��ング、ワイルドカード権限、E��剰なサービスアカウント権限�E、クラスタリソース、シークレチE��、ワークロードへの不正アクセスを許可します、E/p>

リスク

過度な権限を持つサービスアカウントへのアクセスを得た攻撁E��E�E、シークレチE��の一覧表示、特権付きPodの作�E、デプロイメント�E変更、cluster-adminへの昁E��が可能です。ワイルドカードRBACルールは、Kubernetesにおけるroot権限�E付与に相当します、E/p>

脁E��なコード侁E/h3>
YAML (Kubernetes RBAC) ❁EBad
# ClusterRoleBinding granting cluster-admin to a service account
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: app-admin-binding
subjects:
- kind: ServiceAccount
  name: my-app            # App SA with cluster-admin!
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin      # Full cluster control!
  apiGroup: rbac.authorization.k8s.io

安�Eなコード侁E/h3>
YAML (Kubernetes RBAC) ✁EGood
# Scoped Role with minimum required permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-role
  namespace: my-app-ns
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]     # Read-only, specific resources
  resourceNames: ["app-config"]  # Named resource only
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: app-role-binding
  namespace: my-app-ns
subjects:
- kind: ServiceAccount
  name: my-app
  namespace: my-app-ns
roleRef:
  kind: Role
  name: app-role
  apiGroup: rbac.authorization.k8s.io

対策チェチE��リスチE/h3>

3�E�⃣ K03 - シークレチE��管琁E�E失敁E/h2> Critical

概要E/h3>

KubernetesのSecretsは、デフォルトではbase64エンコードされてぁE��だけで、暗号化されてぁE��せん。機寁E��ータ(APIキー、データベ�Eスパスワード、TLS証明書)を平斁E�EConfigMap、環墁E��数、暗号化されてぁE��いSecretsに保存すると、APIアクセス権を持つ誰にでも晒されます。また、etcdでの静止状態�E暗号化が有効になってぁE��ぁE��合、Secretsはetcdで可視化されます、E/p>

リスク

漏洩したシークレチE��により、攻撁E��E�EチE�Eタベ�Eス、クラウドアカウント、外部サービスへアクセスできます。暗号化なしでetcdに保存されたSecretsは、etcdアクセス権を持つ誰でも読み取れます。環墁E��数のシークレチE��は、Pod仕様やプロセスリストで可視化されます、E/p>

脁E��なコード侁E/h3>
YAML (Kubernetes) ❁EBad
# Secret in plain ConfigMap  Evisible to anyone
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DB_PASSWORD: "SuperSecret123!"   # Plaintext password!
  API_KEY: "sk-live-abc123xyz"      # API key in ConfigMap!
---
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: myapp:latest
    envFrom:
    - configMapRef:
        name: app-config    # All values as env vars!

安�Eなコード侁E/h3>
YAML (Kubernetes + External Secrets) ✁EGood
# Use External Secrets Operator with a vault backend
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: app-secrets
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: app-secrets
  data:
  - secretKey: db-password
    remoteRef:
      key: secret/myapp/db
      property: password
---
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: myapp@sha256:abc123...
    volumeMounts:
    - name: secrets
      mountPath: /etc/secrets
      readOnly: true          # Mount as read-only files
  volumes:
  - name: secrets
    secret:
      secretName: app-secrets

対策チェチE��リスチE/h3>

4�E�⃣ K04 - クラスタレベルのポリシー実施の欠妁E/h2> High

概要E/h3>

クラスタレベルのポリシーがなければ、安�EでなぁE��ークロード�EチE�Eロイを防ぐガードレールはありません。Pod Security Standards(PSS)、アドミチE��ョンコントローラ、OPA GatekeeperやKyvernoなどのポリシーエンジンは、すべてのnamespaceでセキュリチE��ベ�Eスラインを実施するために不可欠です、E/p>

リスク

ポリシー実施がなければ、どの開発老E��も特権付きコンチE��をデプロイし、hostPathボリュームを使用し、セキュリチE��コントロールを無効化できます。単一の設定ミスのあるワークロードがクラスタ全体を侵害する可能性があります。手動レビューでは、すべての違反を検�Eするのに拡張できません、E/p>

脁E��なコード侁E/h3>
Bash ❁EBad
#!/bin/bash
# No admission control  Eany pod spec is accepted
# No Pod Security Standards configured

# Anyone can deploy a privileged container
kubectl run hacker-pod --image=alpine \
  --overrides='{"spec":{"containers":[{
    "name":"hack",
    "image":"alpine",
    "securityContext":{"privileged":true},
    "command":["nsenter","--target","1","--mount","--uts","--ipc","--net","--pid","--","bash"]
  }]}}'

# No policy blocks this  Enow has host root access!

安�Eなコード侁E/h3>
YAML (Kyverno ClusterPolicy) ✁EGood
# Enforce Pod Security Standards with Kyverno
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged
spec:
  validationFailureAction: Enforce
  background: true
  rules:
  - name: deny-privileged
    match:
      any:
      - resources:
          kinds: ["Pod"]
    validate:
      message: "Privileged containers are not allowed."
      pattern:
        spec:
          containers:
          - securityContext:
              privileged: "false"
  - name: require-run-as-non-root
    match:
      any:
      - resources:
          kinds: ["Pod"]
    validate:
      message: "Containers must run as non-root."
      pattern:
        spec:
          securityContext:
            runAsNonRoot: true

対策チェチE��リスチE/h3>

5�E�⃣ K05 - ネットワーク刁E��制御の欠妁E/h2> High

概要E/h3>

チE��ォルトでは、Kubernetesクラスタ冁E�EすべてのPodは制限なしに相互通信できます。このフラチE��なネットワークアーキチE��チャは、侵害されたPodが他�EPod、サービス、さらにはKubernetes APIサーバ�Eに到達できることを意味します。�EイクロセグメンチE�Eションを実裁E��るには、NetworkPolicyが不可欠です、E/p>

リスク

ネットワーク刁E��がなければ、横方向�E移動�E簡単です。侵害されたフロントエンドPodは、バチE��エンドデータベ�Eス、�E部サービス、メタチE�EタAPI(169.254.169.254)に直接アクセスできます。これ�Eネットワーク層での最小権限�E原則に違反します、E/p>

脁E��なコード侁E/h3>
YAML (Kubernetes) ❁EBad
# No NetworkPolicy  Eall pods can communicate freely
apiVersion: v1
kind: Namespace
metadata:
  name: production
  # No default deny policy
  # No network policies at all
  # Any pod can reach:
  #   - Other pods in any namespace
  #   - Kubernetes API server
  #   - Cloud metadata API (169.254.169.254)
  #   - External internet

安�Eなコード侁E/h3>
YAML (Kubernetes NetworkPolicy) ✁EGood
# Default deny all ingress and egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes: ["Ingress", "Egress"]
---
# Allow only frontend to backend communication
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes: ["Ingress"]
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - port: 8080
      protocol: TCP

対策チェチE��リスチE/h3>

6�E�⃣ K06 - 過度に露出したKubernetesコンポ�EネンチE/h2> High

概要E/h3>

Kubernetesコントロールプレーンコンポ�EネンチEAPIサーバ�E、etcd、kubelet、ダチE��ュボ�EチEとアプリケーションサービスは、誤ってインターネットや信頼できなぁE��チE��ワークに露出する可能性があります。露出したダチE��ュボ�Eド、認証なし�Ekubelet、�E開アクセス可能なAPIサーバ�Eは一般皁E��攻撁E�Eクトルです、E/p>

リスク

露出したKubernetesコンポ�Eネント�E、クラスタ管琁E��の直接アクセスを提供します。認証なし�Ekubelet APIはコンチE��実行を許可します。デフォルト認証惁E��を持つ露出したダチE��ュボ�Eド�E、cluster-adminアクセスを付与します。�E開etcdアクセスは、シークレチE��を含むすべてのクラスタチE�Eタを露出します、E/p>

脁E��なコード侁E/h3>
YAML (Kubernetes Service) ❁EBad
# Kubernetes Dashboard exposed via LoadBalancer
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: LoadBalancer        # Public internet access!
  ports:
  - port: 443
    targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
# Dashboard bound to cluster-admin service account
# No authentication required  Efull cluster access!

安�Eなコード侁E/h3>
YAML (Kubernetes) ✁EGood
# Dashboard accessible only via kubectl proxy
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: ClusterIP           # Internal only
  ports:
  - port: 443
    targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
---
# Access via: kubectl proxy, then browse to:
# http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
# Or use kubectl port-forward for secure access

対策チェチE��リスチE/h3>

7�E�⃣ K07 - 設定ミスと脁E��なクラスタコンポ�EネンチE/h2> High

概要E/h3>

Kubernetesクラスタは多くのコンポ�Eネントで構�EされてぁE��ぁE APIサーバ�E、etcd、kubelet、kube-proxy、CoreDNS、サードパーチE��アドオン(Ingressコントローラ、サービスメチE��ュ、モニタリング)。設定ミスのある、また�Eパッチ未適用のコンポ�Eネント�E脁E��性を招きます。デフォルト設定�E多くの場合強化されてぁE��せん、E/p>

リスク

脁E��なクラスタコンポ�Eネント�E、リモートコード実行、権限�E格、また�Eサービス拒否のために悪用される可能性があります。kubelet、Ingressコントローラ、また�ECNIプラグインのCVEは、コンチE��エスケープとクラスタ乗っ取りにつながる可能性があります。時代遁E��のコンポ�Eネント�E既知の脁E��性を蓄積します、E/p>

脁E��なコード侁E/h3>
YAML (Kubernetes) ❁EBad
# kubelet with insecure configuration
# /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
  anonymous:
    enabled: true              # Anyone can access kubelet API!
  webhook:
    enabled: false             # No authorization!
authorization:
  mode: AlwaysAllow            # All requests permitted!
readOnlyPort: 10255            # Unauthenticated read port open!

安�Eなコード侁E/h3>
YAML (Kubernetes) ✁EGood
# Hardened kubelet configuration
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
  anonymous:
    enabled: false             # Deny anonymous access
  webhook:
    enabled: true              # Use API server for auth
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
  mode: Webhook                # API server authorizes requests
readOnlyPort: 0                # Disable read-only port
protectKernelDefaults: true
eventRecordQPS: 5

対策チェチE��リスチE/h3>

8�E�⃣ K08 - クラスタからクラウドへの横方向移勁E/h2> Critical

概要E/h3>

クラウド環墁EAWS、GCP、Azure)で実行されるKubernetesクラスタは、クラウドメタチE�EタAPIとノ�Eドに付与されたIAMロールにアクセスできます。Podを侵害した攻撁E��E�E、これらを使用してクラスタからクラウドアカウントへ権限を昁E��し、S3バケチE��、データベ�Eス、その他�Eクラウドサービスにアクセスできます、E/p>

リスク

ノ�EドレベルのIAMロールは、そのノ�Eド上�EすべてのPodに継承されます。侵害されたPodは、メタチE�EタAPI(169.254.169.254)にクエリしてクラウド認証惁E��を取得し、ノードロールが許可するあらめE��クラウドリソースにアクセスできます。これにより、Kubernetesから庁E��E��クラウド環墁E��の横方向�E移動が可能になります、E/p>

脁E��なコード侁E/h3>
Terraform (AWS EKS) ❁EBad
# Node IAM role with excessive permissions
resource "aws_iam_role_policy_attachment" "node_admin" {
  role       = aws_iam_role.node_role.name
  policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
  # All pods on this node inherit admin access!
}

# No IMDS restrictions  Eany pod can get node credentials
# curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

安�Eなコード侁E/h3>
Terraform (AWS EKS with IRSA) ✁EGood
# Use IAM Roles for Service Accounts (IRSA)
resource "aws_iam_role" "app_role" {
  name = "my-app-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = {
        Federated = aws_iam_openid_connect_provider.eks.arn
      }
      Action = "sts:AssumeRoleWithWebIdentity"
      Condition = {
        StringEquals = {
          "${aws_iam_openid_connect_provider.eks.url}:sub" =
            "system:serviceaccount:my-ns:my-app"
        }
      }
    }]
  })
}

# Pod-level scoped IAM via service account annotation
# Only this specific pod gets these specific permissions

対策チェチE��リスチE/h3>

9�E�⃣ K09 - 破損した認証メカニズム

Critical

概要E/h3>

Kubernetesは褁E��の認証メカニズムをサポ�EトしてぁE��ぁE 証明書、トークン、OIDC、Webhook認証。破損した認証には、E��皁E��ークンの使用、kubeconfigファイルの共有、証明書のローチE�Eション不足、アイチE��チE��チE��プロバイダーとの統合失敗が含まれます。サービスアカウントトークンの自動�Eウント�E不忁E��な攻撁E��を生み出します、E/p>

リスク

盗まれたまた�E漏洩したkubeconfigファイルとサービスアカウントトークンは、クラスタへの直接アクセスを提供します。期限�EれにならなぁE��皁E��ークンは永続的なアクセスを与えます。集中化されたアイチE��チE��チE��管琁E��なければ、E��職したチ�Eムメンバ�Eのアクセス取り消しは困難でエラーが発生しめE��くなります、E/p>

脁E��なコード侁E/h3>
YAML (Kubernetes) ❁EBad
# Static token file for API server authentication
# /etc/kubernetes/token-auth-file.csv
# token,user,uid,"groups"
# abc123,admin,1,"system:masters"  # Static token, never expires!

# Pod with auto-mounted service account token
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  # automountServiceAccountToken defaults to true!
  # Token mounted at /var/run/secrets/kubernetes.io/serviceaccount/token
  containers:
  - name: app
    image: myapp:latest
    # App doesn't need K8s API access but has a token anyway

安�Eなコード侁E/h3>
YAML (Kubernetes) ✁EGood
# Disable auto-mounted token for pods that don't need API access
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app
  namespace: my-app-ns
automountServiceAccountToken: false  # No auto-mount
---
# For pods that need API access, use bound tokens with expiry
apiVersion: v1
kind: Pod
metadata:
  name: api-consumer
spec:
  serviceAccountName: api-consumer-sa
  automountServiceAccountToken: false
  containers:
  - name: app
    image: myapp@sha256:abc123...
    volumeMounts:
    - name: token
      mountPath: /var/run/secrets/tokens
      readOnly: true
  volumes:
  - name: token
    projected:
      sources:
      - serviceAccountToken:
          expirationSeconds: 3600  # 1-hour expiry
          audience: api-server

対策チェチE��リスチE/h3>

🔟 K10 - 不十刁E��ログ記録と監要E/h2> Medium

概要E/h3>

KubernetesはAPIサーバ�Eリクエスト�E監査イベントを生�Eしますが、監査ログは無効化されてぁE��か、設定ミスが多くあります。適刁E��ログ記録と監視がなければ、不正なシークレチE��アクセス、RBAC変更、コンチE��エスケープなどの悪意ある活動�E検�Eされません。コンチE��とノ�EドレベルでのランタイムセキュリチE��監視が不可欠です、E/p>

リスク

監査ログがなければ、攻撁E��E�E検�Eされずに活動します。バチE��ドアサービスアカウント�E作�E、シークレチE��の抽出、ワークロード�E変更を記録なしで行えます。何が起こったか、いつ、誰によってかを判断する監査証跡がなぁE��合、インシチE��ト対応�E深刻に損なわれます、E/p>

脁E��なコード侁E/h3>
YAML (Kubernetes) ❁EBad
# API server with no audit logging configured
# kube-apiserver flags:
#   --audit-log-path=""           # No audit log!
#   --audit-policy-file=""        # No audit policy!

# No runtime security monitoring
# No alerting on suspicious activities
# Container logs not collected centrally
# Default log retention  Elogs lost on pod restart

安�Eなコード侁E/h3>
YAML (Kubernetes Audit Policy) ✁EGood
# Comprehensive audit policy
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Log all secret access at Metadata level
- level: Metadata
  resources:
  - group: ""
    resources: ["secrets"]
# Log RBAC changes at RequestResponse level
- level: RequestResponse
  resources:
  - group: rbac.authorization.k8s.io
    resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
# Log pod exec/attach (potential attacks)
- level: Request
  resources:
  - group: ""
    resources: ["pods/exec", "pods/attach", "pods/portforward"]
# Default: log at Metadata level
- level: Metadata

対策チェチE��リスチE/h3>

📊 サマリーチE�Eブル

ID 脁E��性 深刻度 主な対筁E/th>
K01安�EでなぁE��ークロード設宁E/td>Critical非root、読み取り専用FS、ケーパビリチE��削除、リソース制陁E/td>
K02過度に寛容な認可設宁E/td>CriticalNamespace-scoped RBAC、ワイルドカード禁止、バインチE��ング監査
K03シークレチE��管琁E�E失敁E/td>Critical外部シークレチE��、E��止状態�E暗号化、ファイルマウンチE/td>
K04ポリシー実施の欠妁E/td>HighPod Security Standards、Kyverno/OPA Gatekeeper
K05ネットワーク刁E��制御の欠妁E/td>HighDefault-deny NetworkPolicy、�EイクロセグメンチE�Eション
K06過度に露出したコンポ�EネンチE/td>HighClusterIPサービス、kubectl proxy、ファイアウォールルール
K07設定ミスと脁E��なクラスタコンポ�EネンチE/td>HighCIS Benchmark、匿名認証無効化、パチE��管琁E/td>
K08クラスタからクラウドへの横方向移勁E/td>CriticalIRSA/Workload Identity、メタチE�EタAPIブロチE��、IMDSv2
K09破損した認証メカニズムCriticalOIDC統合、バウンドトークン、�E動�Eウント無効匁E/td>
K10不十刁E��ログ記録と監要E/td>Medium監査ログ、Falco/Tetragon、SIEM統吁E/td>