Segurança em pipelines de CI/CD
1. Fundamentos da Segurança em Pipelines
1.1. O que são pipelines de CI/CD e por que são alvos críticos
Pipelines de CI/CD automatizam a construção, teste e deploy de software. Eles representam o caminho crítico entre o código-fonte e a produção. Por concentrarem acesso a múltiplos sistemas, repositórios e credenciais, tornam-se alvos prioritários para atacantes. Uma única vulnerabilidade no pipeline pode comprometer toda a cadeia de fornecimento de software.
1.2. Ameaças comuns: injeção de código, vazamento de secrets e supply chain attacks
As principais ameaças incluem:
- Injeção de código: parâmetros maliciosos em triggers de pull requests
- Vazamento de secrets: tokens expostos em logs de build ou variáveis de ambiente
- Supply chain attacks: dependências comprometidas inseridas durante o build
1.3. Princípios de confiança zero aplicados a pipelines
Confiança zero significa nunca confiar automaticamente em nenhuma etapa do pipeline. Cada job deve verificar identidades, validar entradas e operar com privilégios mínimos. Exemplo de configuração mínima:
# .gitlab-ci.yml com princípios de confiança zero
stages:
- verify
- build
- test
- deploy
variables:
GIT_DEPTH: "1" # Reduz superfície de ataque
before_script:
- echo "Verificando ambiente seguro..."
- env | grep -i "token\|secret\|password" > /dev/null && exit 1 || true
2. Proteção de Credenciais e Secrets no Pipeline
2.1. Gerenciamento seguro de secrets
Nunca armazene secrets diretamente no código ou configurações do pipeline. Use cofres externos como HashiCorp Vault, AWS Secrets Manager ou Azure Key Vault.
# Exemplo: recuperando secret do Vault no pipeline
vault read -field=value secret/ci/github-token > /tmp/github_token
export GITHUB_TOKEN=$(cat /tmp/github_token)
rm -f /tmp/github_token
2.2. Evitando hardcoding
Nunca coloque tokens ou chaves SSH em arquivos YAML ou scripts versionados. Utilize variáveis de ambiente criptografadas da ferramenta de CI:
# GitHub Actions - secrets criptografados
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy with secure token
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
run: ./deploy.sh --token "$DEPLOY_TOKEN"
2.3. Rotação e revogação automática
Implemente políticas de rotação automática para todas as credenciais usadas no pipeline:
# Script de rotação de chaves SSH
#!/bin/bash
# Gerar nova chave e atualizar no cofre
ssh-keygen -t ed25519 -f /tmp/deploy_key -N ""
vault write secret/ci/deploy-key key=@/tmp/deploy_key
# Remover chave antiga dos servidores
ansible-playbook rotate-keys.yml
3. Controle de Acesso e Permissões no Pipeline
3.1. RBAC em ferramentas de CI/CD
Configure permissões granulares para quem pode modificar jobs e configurações:
# Exemplo de permissões no GitHub Actions
permissions:
contents: read
pull-requests: write
deployments: write
3.2. Isolamento de estágios e ambientes
Separe claramente ambientes de desenvolvimento, staging e produção:
# Jenkinsfile com ambientes isolados
pipeline {
agent none
stages {
stage('Build') {
agent { label 'build-node' }
steps { sh 'make build' }
}
stage('Test') {
agent { label 'test-node' }
steps { sh 'make test' }
}
stage('Deploy Staging') {
agent { label 'staging-node' }
when { branch 'develop' }
steps { sh 'deploy staging' }
}
stage('Deploy Production') {
agent { label 'prod-node' }
when { branch 'main' }
input { message 'Confirmar deploy em produção?' }
steps { sh 'deploy production' }
}
}
}
3.3. Uso de identidades efêmeras
Utilize tokens de curta duração e identidades temporárias para cada execução:
# Azure DevOps - token efêmero
- task: AzureCLI@2
inputs:
azureSubscription: '$(serviceConnection)'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
# Token válido apenas durante o job
az account get-access-token --resource https://vault.azure.net
4. Segurança na Execução de Scripts e Comandos
4.1. Validação de entrada e sanitização
Nunca execute comandos diretamente com parâmetros de usuários ou branches:
# Perigoso: injeção de comando
- run: echo "Branch: ${{ github.head_ref }}"
# Seguro: validação e sanitização
- name: Validate branch name
run: |
BRANCH="${{ github.head_ref }}"
if [[ ! "$BRANCH" =~ ^[a-zA-Z0-9_/-]+$ ]]; then
echo "Branch name contains invalid characters"
exit 1
fi
echo "Branch validated: $BRANCH"
4.2. Evitando injeção via variáveis
Proteja-se contra injeção através de variáveis de ambiente e artefatos:
# Exemplo seguro: escapando variáveis
- name: Safe variable usage
env:
USER_INPUT: ${{ github.event.pull_request.title }}
run: |
# Escapar caracteres especiais
SAFE_INPUT=$(echo "$USER_INPUT" | sed 's/[^a-zA-Z0-9]//g')
echo "Processed: $SAFE_INPUT"
4.3. Uso de runners seguros
Utilize runners efêmeros em containers ou VMs descartáveis:
# GitHub Actions - runner em container
jobs:
build:
runs-on: ubuntu-latest
container:
image: node:18-alpine
options: --read-only --cap-drop=ALL
5. Verificação de Dependências e Artefatos
5.1. Escaneamento de vulnerabilidades
Integre ferramentas de SBOM e análise de dependências:
# Geração de SBOM com Syft
- name: Generate SBOM
run: |
syft packages dir:. -o cyclonedx-json > sbom.json
# Escaneamento com Trivy
- name: Scan for vulnerabilities
run: |
trivy fs --severity CRITICAL,HIGH .
5.2. Assinatura e verificação de artefatos
Assine imagens Docker e pacotes antes do deploy:
# Assinatura de imagem Docker com Cosign
- name: Sign Docker image
run: |
cosign sign --key cosign.key \
registry.example.com/app:${GITHUB_SHA}
5.3. Políticas de aprovação manual
Implemente gates de aprovação para estágios críticos:
# GitHub Environments com proteção
environment:
name: production
url: https://app.example.com
protection_rules:
- required_reviewers: ['security-team']
- wait_timer: 300
6. Monitoramento e Auditoria de Pipelines
6.1. Logs centralizados e alertas
Configure alertas para atividades suspeitas:
# Logging para auditoria
- name: Audit pipeline execution
run: |
echo "{\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"pipeline\":\"$GITHUB_RUN_ID\",\"actor\":\"$GITHUB_ACTOR\",\"event\":\"$GITHUB_EVENT_NAME\"}" | \
curl -X POST -H "Content-Type: application/json" \
-d @- https://logs.example.com/audit
6.2. Imutabilidade de logs
Garanta que logs de build não possam ser adulterados:
# Envio de logs para armazenamento imutável
- name: Store immutable logs
run: |
cat build.log | openssl dgst -sha256 -sign private.key > build.log.sig
aws s3 cp build.log s3://immutable-logs/ --storage-class GLACIER
6.3. Revisão periódica
Agende auditorias regulares das configurações:
# Script de auditoria de permissões
#!/bin/bash
# Verificar permissões excessivas em workflows
for file in .github/workflows/*.yml; do
if grep -q "permissions: write-all" "$file"; then
echo "ALERTA: $file tem permissões excessivas"
fi
done
7. Integração com Ferramentas de Segurança (SAST/DAST)
7.1. Gatilhos automáticos para análise estática
Execute SAST em cada commit e pull request:
# GitHub Actions com Semgrep
- name: SAST Scan
uses: semgrep/semgrep-action@v1
with:
config: p/default
severity: ERROR
7.2. Testes dinâmicos em staging
Realize DAST antes do deploy em produção:
# DAST com OWASP ZAP
- name: DAST Scan
run: |
docker run -v $(pwd):/zap/wrk/:rw \
ghcr.io/zaproxy/zaproxy:stable \
zap-full-scan.py -t https://staging.example.com \
-r report.html
7.3. Quebra de pipeline por severidade
Configure thresholds para bloquear deploys com vulnerabilidades críticas:
# Política de quebra de pipeline
- name: Check vulnerability threshold
run: |
CRITICAL=$(jq '.results[].vulnerabilities | length' trivy-report.json)
if [ "$CRITICAL" -gt 0 ]; then
echo "Pipeline bloqueado: $CRITICAL vulnerabilidades críticas encontradas"
exit 1
fi
Referências
- OWASP Cheat Sheet: CI/CD Security — Guia prático da OWASP com recomendações específicas para segurança em pipelines de CI/CD
- GitHub Security Lab: Securing CI/CD Pipelines — Pesquisa e ferramentas do GitHub para identificação de vulnerabilidades em pipelines
- HashiCorp Vault Documentation: CI/CD Integration — Documentação oficial sobre integração do Vault com pipelines de CI/CD
- SLSA Framework: Supply Chain Levels for Software Artifacts — Framework para garantir integridade da cadeia de fornecimento de software em pipelines
- Docker: Signing Images with Cosign — Tutorial oficial sobre assinatura e verificação de imagens Docker em pipelines
- Semgrep: SAST Integration in CI/CD — Guia de integração de análise estática em pipelines com exemplos práticos
- Trivy: Vulnerability Scanner for CI/CD — Documentação oficial do scanner de vulnerabilidades para pipelines CI/CD