클라우드 네이티브 애플리케이션 보안 톱 10은 무엇인가요?

OWASP 클라우드 네이티브 애플리케이션 보안 톱 10은 쿠버네티스, 도커, 서버리스 아키텍처와 같은 플랫폼에서 실행되는 클라우드 네이티브 애플리케이션의 가장 두드러진 보안 위험을 식별합니다. 여기에는 전체 클라우드 네이티브 스택에 걸쳐 잘못된 구성, 공급망 위험, 기밀 관리 등이 포함됩니다.

1️⃣ CNAS-1 - 안전하지 않은 클라우드, 컨테이너 또는 오케스트레이션 구성

Critical

개요

잘못 구성된 클라우드 서비스, 컨테이너, 오케스트레이터는 클라우드 네이티브 침해의 주요 원인입니다. 여기에는 컨테이너를 루트로 실행하거나, 기본 구성을 사용하거나, Kubernetes API 서버를 공개적으로 노출하거나, 클라우드 리소스에 대한 감사 로깅을 활성화하지 않은 경우 등이 포함됩니다.

위험

공격자는 잘못된 구성을 악용하여 클러스터를 완전히 제어하거나, 컨테이너를 탈출하거나, 클라우드 메타데이터 서비스에 액세스하거나, 인프라 전반을 피벗할 수 있습니다. 잘못 구성된 하나의 S3 버킷이나 개방형 Kubernetes 대시보드로 인해 대규모 데이터 유출이 발생하기도 합니다.

취약한 코드 예시

Dockerfile ❌ Bad
# Running container as root with no resource limits
FROM ubuntu:latest
RUN apt-get update && apt-get install -y curl wget
COPY app /app
# No USER directive — runs as root!
CMD ["/app/server"]

보안 코드 예시

Dockerfile ✅ Good
FROM gcr.io/distroless/static:nonroot
COPY --chown=65534:65534 app /app
USER 65534:65534
EXPOSE 8080
ENTRYPOINT ["/app/server"]

완화 체크리스트

2️⃣ CNAS-2 - 인젝션 결함(앱 계층, 클라우드 이벤트, 클라우드 서비스)

Critical

개요

클라우드 네이티브 애플리케이션은 기존 HTTP 요청뿐만 아니라 클라우드 이벤트(SQS, Pub/Sub, EventBridge), 서버리스 트리거, 서비스 간 통신으로부터도 입력을 받습니다. 이러한 벡터 중 하나에서 인젝션 결함이 발생하면 명령 실행, 데이터 유출 또는 권한 상승으로 이어질 수 있습니다.

위험

클라우드 이벤트에 의해 트리거되는 서버리스 함수는 유효성 검사 없이 신뢰할 수 없는 데이터를 처리하여 OS 명령 인젝션, NoSQL 인젝션 또는 이벤트 기반 SSRF를 유발할 수 있습니다. 공격자는 메시지 큐나 이벤트 버스를 오염시켜 다운스트림 서비스를 손상시킬 수 있습니다.

취약한 코드 예시

Python ❌ Bad
# Lambda function processing S3 event without sanitizing filename
import os

def handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']
    # Command injection via crafted filename!
    os.system(f"aws s3 cp s3://{bucket}/{key} /tmp/{key}")

보안 코드 예시

Python ✅ Good
import boto3, re
from urllib.parse import unquote_plus

def handler(event, context):
    s3 = boto3.client('s3')
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = unquote_plus(event['Records'][0]['s3']['object']['key'])

    # Validate key against allowlist pattern
    if not re.match(r'^[\w\-./]+$', key):
        raise ValueError(f"Invalid S3 key: {key}")

    # Use SDK instead of shell commands
    s3.download_file(bucket, key, f'/tmp/{key.split("/")[-1]}')

완화 체크리스트

3️⃣ CNAS-3 - 부적절한 인증 및 권한 부여

Critical

개요

클라우드 네이티브 환경에는 클라우드 IAM, Kubernetes RBAC, 서비스 메시 mTLS, 애플리케이션 수준 인증 등 여러 계층의 ID가 포함됩니다. 어느 계층에서든 잘못 구성되거나 지나치게 허용적인 정책을 사용하면 측면 이동, 권한 에스컬레이션 또는 민감한 리소스에 대한 무단 액세스가 허용될 수 있습니다.

위험

파드에 과도하게 허용된 IAM 역할은 워크로드에 전체 클라우드 계정에 대한 액세스 권한을 부여할 수 있습니다. 서비스 간 인증이 누락되면 손상된 파드가 다른 서비스를 가장할 수 있습니다.

취약한 코드 예시

YAML (Kubernetes) ❌ Bad
# Overly permissive ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: default-admin
subjects:
- kind: ServiceAccount
  name: default          # Default SA — shared by all pods!
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin    # Full cluster access!
  apiGroup: rbac.authorization.k8s.io

보안 코드 예시

YAML (Kubernetes) ✅ Good
# Dedicated ServiceAccount with minimal Role
apiVersion: v1
kind: ServiceAccount
metadata:
  name: order-service
  namespace: production
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456:role/order-svc
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: order-service-role
  namespace: production
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get"]

완화 체크리스트

4️⃣ CNAS-4 - CI/CD 파이프라인 및 소프트웨어 공급망 결함

High

개요

CI/CD 파이프라인은 프로덕션 환경에 대한 쓰기 권한이 있기 때문에 가치가 높은 공격 대상입니다. 빌드 파이프라인이 손상되면 공급망 공격, 악성 코드 삽입, 백도어 이미지 배포가 가능해집니다. 안전하지 않은 파이프라인 구성, 포이즌된 기본 이미지, 서명되지 않은 아티팩트가 모두 이러한 위험의 원인이 됩니다.

위험

손상된 CI/CD 파이프라인은 모든 환경에 악성 코드를 배포하고, 파이프라인 변수에 저장된 기밀을 훔치거나 컨테이너 이미지를 변조할 수 있습니다. 솔라윈즈 스타일의 공격은 공급망 침해가 얼마나 치명적인 영향을 미치는지 보여줍니다.

취약한 코드 예시

YAML (GitHub Actions) ❌ Bad
# Insecure CI pipeline — unpinned actions, no image signing
name: Deploy
on: push
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@main   # Unpinned — could be compromised!
    - run: |
        docker build -t myapp:latest .
        docker push myregistry/myapp:latest  # No signing!
        kubectl apply -f deploy.yaml         # No admission control!

보안 코드 예시

YAML (GitHub Actions) ✅ Good
name: Secure Deploy
on: push
permissions:
  id-token: write
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29  # Pinned SHA
    - run: |
        docker build -t myregistry/myapp:${{ github.sha }} .
        cosign sign myregistry/myapp:${{ github.sha }}  # Sign image
    - run: trivy image myregistry/myapp:${{ github.sha }} --exit-code 1
    - run: kubectl apply -f deploy.yaml  # Admission controller verifies signatures

완화 체크리스트

5️⃣ CNAS-5 - 안전하지 않은 비밀 저장소

Critical

개요

API 키, 데이터베이스 자격 증명, TLS 인증서와 같은 시크릿은 소스 코드에 하드코딩되거나, 일반 텍스트 컨피그맵에 저장되거나, 컨테이너 이미지에 임베드되는 경우가 많습니다. 쿠버네티스 시크릿은 기본적으로 암호화되지 않고 base64로만 인코딩되어 최소한의 보호만 제공합니다.

위험

노출된 비밀은 공격자가 데이터베이스, 클라우드 계정 및 타사 서비스에 직접 액세스할 수 있게 해줍니다. Git 기록, 컨테이너 레이어 또는 환경 변수의 비밀은 쉽게 발견되고 악용될 수 있습니다.

취약한 코드 예시

YAML (Kubernetes) ❌ Bad
# Secrets in plaintext environment variables
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    env:
    - name: DB_PASSWORD
      value: "SuperSecret123!"   # Plaintext in manifest!
    - name: AWS_SECRET_KEY
      value: "AKIA..."             # Cloud credentials in YAML!

보안 코드 예시

YAML (Kubernetes) ✅ Good
# Use External Secrets Operator with a vault backend
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: my-app-secrets
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: my-app-secrets
  data:
  - secretKey: db-password
    remoteRef:
      key: secret/data/myapp
      property: db-password

완화 체크리스트

6️⃣ CNAS-6 - 과도하게 허용되거나 안전하지 않은 네트워크 정책

High

개요

기본적으로 쿠버네티스는 모든 파드가 제한 없이 서로 통신할 수 있도록 허용합니다. 누락되거나 지나치게 허용적인 네트워크 정책, 보안 그룹 및 방화벽 규칙은 클러스터 내에서 그리고 클라우드 서비스 간에 횡방향 이동을 가능하게 합니다.

위험

네트워크 세분화가 없으면 손상된 파드는 클러스터의 다른 서비스에 도달하거나 데이터베이스에 직접 액세스하거나 외부 엔드포인트로 데이터를 유출할 수 있습니다. 플랫 네트워크는 모든 침해의 폭발 반경을 증폭시킵니다.

취약한 코드 예시

YAML (Kubernetes) ❌ Bad
# No NetworkPolicy — all pods can talk to everything
apiVersion: v1
kind: Namespace
metadata:
  name: production
# No NetworkPolicy resources defined
# All ingress and egress traffic is allowed by default

보안 코드 예시

YAML (Kubernetes) ✅ Good
# Default-deny all traffic, then allow only what's needed
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes: ["Ingress", "Egress"]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-api
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-server
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - port: 8080

완화 체크리스트

7️⃣ CNAS-7 - 알려진 취약점이 있는 구성 요소 사용

High

개요

클라우드 네이티브 애플리케이션은 오픈 소스 기본 이미지, 라이브러리 및 Kubernetes 운영자에 크게 의존합니다. 오래된 구성 요소나 패치되지 않은 구성 요소를 실행하면 애플리케이션이 잘 문서화된 익스플로잇에 노출됩니다. 컨테이너 이미지에는 수백 개의 패키지가 포함되어 있는 경우가 많으며, 각 패키지는 잠재적인 취약점이 있습니다.

위험

기본 이미지의 알려진 취약점(예: Log4Shell, OpenSSL 버그)은 공개적으로 사용 가능한 도구를 사용하여 익스플로잇할 수 있습니다. 공격자는 취약한 버전을 실행하는 컨테이너를 적극적으로 검색합니다. 패치되지 않은 라이브러리 하나만으로도 전체 워크로드가 손상될 수 있습니다.

취약한 코드 예시

Dockerfile ❌ Bad
# Using outdated base image with known CVEs
FROM node:14                    # EOL version with known vulns
COPY package.json .
RUN npm install                 # No audit, no lockfile verification
COPY . .
CMD ["node", "server.js"]

보안 코드 예시

Dockerfile ✅ Good
# Use current, slim base image with vulnerability scanning
FROM node:22-slim AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production    # Reproducible install from lockfile
RUN npm audit --audit-level=high # Fail on high+ vulns

FROM gcr.io/distroless/nodejs22-debian12
COPY --from=build /app /app
CMD ["/app/server.js"]

완화 체크리스트

8️⃣ CNAS-8 - 부적절한 자산 관리

Medium

개요

클라우드 네이티브 환경에서는 리소스를 쉽게 스핀업할 수 있지만 추적하기는 어렵습니다. 고아가 된 컨테이너, 잊혀진 네임스페이스, 오래된 클라우드 리소스, 섀도 IT 배포는 관리되지 않는 공격 표면을 만듭니다. 적절한 자산 인벤토리가 없으면 보안팀은 존재 여부도 모르는 자산을 보호할 수 없습니다.

위험

잊혀지거나 관리되지 않는 리소스는 오래된 소프트웨어를 실행하고 보안 모니터링이 부족하며 오래된 자격 증명이 있는 경우가 많습니다. 공격자들은 모니터링이나 패치 가능성이 낮기 때문에 이러한 방치된 자산을 공격의 진입 지점으로 삼습니다.

취약한 코드 예시

Terraform ❌ Bad
# Resources created without tagging or lifecycle management
resource "aws_instance" "test_server" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.medium"
  # No tags — who owns this? What's it for?
  # No lifecycle policy — runs forever
}

resource "aws_s3_bucket" "temp_data" {
  bucket = "temp-data-2024"
  # No expiration, no access logging
}

보안 코드 예시

Terraform ✅ Good
resource "aws_instance" "test_server" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.medium"

  tags = {
    Name        = "test-server"
    Owner       = "platform-team"
    Environment = "staging"
    ManagedBy   = "terraform"
    ExpiresAt   = "2026-04-30"
  }
}

resource "aws_s3_bucket" "temp_data" {
  bucket = "temp-data-2024"

  tags = {
    Owner     = "data-team"
    ManagedBy = "terraform"
  }

  lifecycle_rule {
    enabled = true
    expiration { days = 90 }
  }
}

완화 체크리스트

9️⃣ CNAS-9 - 부적절한 컴퓨팅 리소스 할당량 제한

Medium

개요

적절한 리소스 할당량과 제한이 없으면 하나의 잘못된 동작 또는 손상된 워크로드가 사용 가능한 모든 CPU, 메모리 또는 스토리지를 소비하여 다른 애플리케이션에 대한 서비스 거부를 일으킬 수 있습니다. 크립토재킹 공격은 리소스 제한이 없는 환경에서 특히 흔합니다.

위험

공격자는 모든 클러스터 리소스를 소비하는 크립토마이닝 컨테이너 또는 리소스 집약적인 워크로드를 배포할 수 있습니다. 한 포드에서 포크 폭탄이나 메모리 누수가 발생하면 전체 노드가 다운되어 함께 배치된 모든 워크로드에 영향을 미칠 수 있습니다.

취약한 코드 예시

YAML (Kubernetes) ❌ Bad
# Pod with no resource limits
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: myapp:latest
    # No resources block — can consume unlimited CPU/memory!

보안 코드 예시

YAML (Kubernetes) ✅ Good
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: myapp:1.2.3
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"
      limits:
        cpu: "500m"
        memory: "512Mi"
---
# Namespace-level quota
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"

완화 체크리스트

🔟 CNAS-10 - 비효율적인 로깅 및 모니터링

High

개요

클라우드 네이티브 환경은 애플리케이션, 컨테이너 런타임, 오케스트레이터, 서비스 메시, 클라우드 플랫폼 등 여러 계층에 걸쳐 로그를 생성합니다. 중앙 집중식 로깅, 이러한 계층 간의 상관관계, 런타임 위협 탐지가 없으면 보안 인시던트가 탐지되지 않거나 너무 늦게 발견됩니다.

위험

임시 컨테이너는 종료되면 로그가 손실되어 포렌식 증거가 파괴됩니다. Kubernetes 감사 로그와 런타임 모니터링이 없으면 공격자는 백도어를 생성하거나 권한을 에스컬레이션하거나 경고를 트리거하지 않고도 데이터를 유출할 수 있습니다.

취약한 코드 예시

YAML (Kubernetes) ❌ Bad
# No audit policy, no log forwarding
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: myapp:latest
    # Logs go to stdout only — lost when pod restarts
    # No audit logging configured on the cluster
    # No runtime security monitoring

보안 코드 예시

YAML (Kubernetes) ✅ Good
# Kubernetes audit policy for security events
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
  resources:
  - group: ""
    resources: ["secrets", "configmaps"]
- level: Metadata
  resources:
  - group: "rbac.authorization.k8s.io"
    resources: ["clusterroles", "clusterrolebindings"]
- level: Metadata
  verbs: ["create", "delete", "patch"]
# Deploy Falco for runtime threat detection
# Forward logs to SIEM via Fluent Bit / Fluentd

완화 체크리스트

📊 요약 표

ID 취약성 심각도 주요 완화
CNAS-1안전하지 않은 클라우드/컨테이너/오케스트레이션 구성Critical배포되지 않은 이미지, 포드 보안 표준, IaC 스캔
CNAS-2주입 결함(클라우드 이벤트)Critical입력 유효성 검사, SDK 오버 셸, 송신 필터링
CNAS-3부적절한 인증 및 권한 부여Critical최소 권한 RBAC, IRSA, mTLS
CNAS-4CI/CD 파이프라인 및 공급망 결함High고정 SHA, 이미지 서명, SLSA 출처 증명
CNAS-5안전하지 않은 비밀 저장소Critical볼트/시크릿 관리자, KMS 암호화, 비밀 스캔
CNAS-6과도하게 허용되는 네트워크 정책High기본 거부, 송신 제한, 캘리코/실리움
CNAS-7알려진 취약점이 있는 구성 요소High이미지 스캔, 최소한의 기본 이미지, SBOM
CNAS-8부적절한 자산 관리Medium리소스 태깅, 자동 정리, IaC
CNAS-9부적절한 컴퓨팅 리소스 할당량Medium리소스 제한, 리소스 할당량, 사용량 모니터링
CNAS-10비효율적인 로깅 및 모니터링High감사 로그, Falco/Sysdig, 중앙 집중식 SIEM