Os 10 riscos de segurança mais críticos para aplicações nativas de nuvem e como mitigá-los.
O OWASP Cloud-Native Application Security Top 10 identifica os riscos de segurança mais proeminentes para aplicações nativas de nuvem executadas em plataformas como Kubernetes, Docker e arquiteturas serverless. Abrange configurações incorretas, riscos de cadeia de suprimentos, gerenciamento de segredos e muito mais em toda a pilha nativa de nuvem.
Serviços de nuvem, contêineres e orquestradores mal configurados são a principal causa de violações nativas de nuvem. Isso inclui executar contêineres como root, usar configurações padrão, expor o servidor de API do Kubernetes publicamente e não habilitar o registro de auditoria em recursos de nuvem.
Invasores podem explorar configurações incorretas para obter controle total do cluster, escapar de contêineres, acessar serviços de metadados de nuvem ou pivotar pela infraestrutura. Um único bucket S3 mal configurado ou painel Kubernetes aberto levou a violações massivas de dados.
# 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 Eruns as root! CMD ["/app/server"]
FROM gcr.io/distroless/static:nonroot COPY --chown=65534:65534 app /app USER 65534:65534 EXPOSE 8080 ENTRYPOINT ["/app/server"]
Aplicações nativas de nuvem recebem entrada não apenas de requisições HTTP tradicionais, mas também de eventos de nuvem (SQS, Pub/Sub, EventBridge), gatilhos serverless e comunicação entre serviços. Falhas de injeção em qualquer um desses vetores podem levar à execução de comandos, exfiltração de dados ou escalação de privilégios.
Funções serverless acionadas por eventos de nuvem podem processar dados não confiáveis sem validação, levando a injeção de comando do SO, injeção NoSQL ou SSRF orientado por eventos. Invasores podem envenenar filas de mensagens ou barramentos de eventos para comprometer serviços downstream.
# 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}")
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]}')
Ambientes nativos de nuvem envolvem várias camadas de identidade: IAM de nuvem, RBAC do Kubernetes, mTLS de malha de serviço e autenticação em nível de aplicação. Políticas mal configuradas ou excessivamente permissivas em qualquer camada podem permitir movimento lateral, escalação de privilégios ou acesso não autorizado a recursos sensíveis.
Funções IAM excessivamente permissivas atribuídas a pods podem conceder acesso a cargas de trabalho para toda a conta de nuvem. A falta de autenticação serviço-a-serviço permite que qualquer pod comprometido se passe por outros serviços.
# Overly permissive ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: default-admin subjects: - kind: ServiceAccount name: default # Default SA Eshared by all pods! namespace: default roleRef: kind: ClusterRole name: cluster-admin # Full cluster access! apiGroup: rbac.authorization.k8s.io
# 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"]
Pipelines CI/CD são alvos de alto valor porque têm acesso de gravação aos ambientes de produção. Comprometer um pipeline de build permite ataques à cadeia de suprimentos, injeção de código malicioso e implantação de imagens com backdoor. Configurações inseguras de pipeline, imagens base envenenadas e artefatos não assinados contribuem para esse risco.
Um pipeline CI/CD comprometido pode implantar código malicioso em todos os ambientes, roubar segredos armazenados em variáveis de pipeline ou adulterar imagens de contêiner. Ataques estilo SolarWinds demonstram o impacto catastrófico do comprometimento da cadeia de suprimentos.
# Insecure CI pipeline Eunpinned actions, no image signing name: Deploy on: push jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@main # Unpinned Ecould be compromised! - run: | docker build -t myapp:latest . docker push myregistry/myapp:latest # No signing! kubectl apply -f deploy.yaml # No admission control!
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
Segredos como chaves de API, credenciais de banco de dados e certificados TLS são frequentemente codificados no código-fonte, armazenados em ConfigMaps de texto simples ou incorporados em imagens de contêiner. Secrets do Kubernetes são apenas codificados em base64 por padrão, não criptografados, fornecendo proteção mínima.
Segredos expostos podem dar aos invasores acesso direto a bancos de dados, contas de nuvem e serviços de terceiros. Segredos no histórico do git, camadas de contêiner ou variáveis de ambiente são facilmente descobertos e explorados.
# 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!
# 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
Por padrão, o Kubernetes permite que todos os pods se comuniquem entre si sem restrição. NetworkPolicies ausentes ou excessivamente permissivas, grupos de segurança e regras de firewall permitem movimento lateral dentro do cluster e entre serviços de nuvem.
Sem segmentação de rede, um pod comprometido pode alcançar qualquer outro serviço no cluster, acessar bancos de dados diretamente ou exfiltrar dados para endpoints externos. Redes planas amplificam o raio de explosão de qualquer violação.
# No NetworkPolicy Eall 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
# 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
Aplicações nativas de nuvem dependem fortemente de imagens base de código aberto, bibliotecas e operadores do Kubernetes. Executar componentes desatualizados ou sem patches com CVEs conhecidos expõe a aplicação a explorações bem documentadas. Imagens de contêiner frequentemente incluem centenas de pacotes, cada um uma vulnerabilidade potencial.
Vulnerabilidades conhecidas em imagens base (por exemplo, Log4Shell, bugs do OpenSSL) podem ser exploradas usando ferramentas publicamente disponíveis. Invasores escaneiam ativamente contêineres executando versões vulneráveis. Uma única biblioteca sem patch pode comprometer toda a carga de trabalho.
# 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"]
# 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"]
Ambientes nativos de nuvem facilitam a criação de recursos, mas dificultam seu rastreamento. Contêineres órfãos, namespaces esquecidos, recursos de nuvem obsoletos e implantações de TI sombra criam uma superfície de ataque não gerenciada. Sem inventário adequado de ativos, equipes de segurança não podem proteger o que não sabem que existe.
Recursos esquecidos ou não gerenciados frequentemente executam software desatualizado, carecem de monitoramento de segurança e têm credenciais obsoletas. Invasores visam esses ativos negligenciados como pontos de entrada porque têm menos probabilidade de serem monitorados ou corrigidos.
# Resources created without tagging or lifecycle management resource "aws_instance" "test_server" { ami = "ami-0abcdef1234567890" instance_type = "t3.medium" # No tags Ewho owns this? What's it for? # No lifecycle policy Eruns forever } resource "aws_s3_bucket" "temp_data" { bucket = "temp-data-2024" # No expiration, no access logging }
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 } } }
Sem quotas e limites de recursos adequados, uma única carga de trabalho com mau funcionamento ou comprometida pode consumir toda a CPU, memória ou armazenamento disponível, causando negação de serviço para outras aplicações. Ataques de cryptojacking são particularmente comuns em ambientes sem limites de recursos.
Invasores podem implantar contêineres de mineração de criptomoedas ou cargas de trabalho intensivas em recursos que consomem todos os recursos do cluster. Sem limites, um fork bomb ou vazamento de memória em um pod pode travar todo o nó, afetando todas as cargas de trabalho colocalizadas.
# Pod with no resource limits apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: app image: myapp:latest # No resources block Ecan consume unlimited CPU/memory!
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"
Ambientes nativos de nuvem geram logs em várias camadas: aplicação, tempo de execução de contêiner, orquestrador, malha de serviço e plataforma de nuvem. Sem registro centralizado, correlação entre essas camadas e detecção de ameaças em tempo de execução, incidentes de segurança passam despercebidos ou são descobertos tarde demais.
Contêineres efêmeros perdem seus logs quando terminados, destruindo evidências forenses. Sem logs de auditoria do Kubernetes e monitoramento em tempo de execução, invasores podem criar backdoors, escalar privilégios ou exfiltrar dados sem acionar nenhum alerta.
# 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 Elost when pod restarts # No audit logging configured on the cluster # No runtime security monitoring
# 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 | Vulnerabilidade | Severidade | Mitigação Principal |
|---|---|---|---|
| CNAS-1 | Configuração Insegura de Nuvem/Contêiner/Orquestração | Critical | Imagens distroless, Pod Security Standards, escaneamento IaC |
| CNAS-2 | Falhas de Injeção (Eventos de Nuvem) | Critical | Validação de entrada, SDK sobre shell, filtragem de saída |
| CNAS-3 | Autenticação e Autorização Inadequadas | Critical | RBAC de privilégio mínimo, IRSA, mTLS |
| CNAS-4 | Falhas de Pipeline CI/CD e Cadeia de Suprimentos | High | SHAs fixados, assinatura de imagem, proveniência SLSA |
| CNAS-5 | Armazenamento Inseguro de Segredos | Critical | Vault/Secrets Manager, criptografia KMS, escaneamento de segredos |
| CNAS-6 | Políticas de Rede Excessivamente Permissivas | High | Negação padrão, restrições de saída, Calico/Cilium |
| CNAS-7 | Componentes com Vulnerabilidades Conhecidas | High | Escaneamento de imagens, imagens base mínimas, SBOM |
| CNAS-8 | Gerenciamento Inadequado de Ativos | Medium | Marcação de recursos, limpeza automatizada, IaC |
| CNAS-9 | Quotas Inadequadas de Recursos Computacionais | Medium | Limites de recursos, ResourceQuotas, monitoramento de uso |
| CNAS-10 | Registro e Monitoramento Ineficazes | High | Logs de auditoria, Falco/Sysdig, SIEM centralizado |