pular para o conteúdo
voltar ao mapa
prática
etapa: ship
2 min de leitura

A02 Security Misconfiguration

Os padrões são feitos para conveniência, não para a internet. Uma flag de debug, um bucket aberto, um erro detalhado ou uma senha padrão transformam código correto em um incidente.

TrivyCheckovScoutSuite / ProwlerMozilla ObservatorynmapOpenSCAP / CIS benchmarks

O que é

Security misconfiguration é qualquer distância entre como um sistema está configurado e como deveria estar: recursos desnecessários habilitados, contas padrão mantidas, modo debug em produção, headers de segurança ausentes, permissões de nuvem permissivas ou stack traces exibidos aos usuários.

É o A02 no :2025 porque está em toda parte e é barato de encontrar: os atacantes varrem a internet inteira atrás dos mesmos poucos erros.

Como o ataque funciona

  • Um framework deixado em modo debug expõe um console interativo ou stack traces completos com caminhos de arquivos e segredos.
  • Um bucket de armazenamento, banco de dados ou painel de administração está acessível pela internet com credenciais padrão ou sem credenciais.
  • Listagem de diretório ou um /.git, /.env ou arquivo de backup esquecido vaza código-fonte e chaves.
  • Parsers XML com entidades externas habilitadas permitem que um documento forjado leia arquivos locais.
  • permissivo (origem curinga com credenciais) permite que qualquer site chame a API como a vítima.

Configuração vulnerável

Três formas comuns: debug ligado, CORS curinga com credenciais e um contêiner público expondo um banco de dados.

app.py (Flask)python
app = Flask(__name__)
app.config["DEBUG"] = True            # debugger interativo acessível em produção
CORS(app, origins="*", supports_credentials=True)
docker-compose.ymlyaml
services:
  db:
    image: postgres:latest
    ports:
      - "5432:5432"            # publicado em todas as interfaces
    environment:
      POSTGRES_PASSWORD: postgres
bucket.tfhcl
resource "aws_s3_bucket_public_access_block" "assets" {
  bucket                  = aws_s3_bucket.assets.id
  block_public_acls       = false
  block_public_policy     = false
}

A correção

Faça da configuração segura o padrão e construa-a uma vez: uma imagem base reforçada, um módulo de configuração revisado e as mesmas configurações em todos os ambientes, aplicadas a partir de código. Remova o que você não usa.

app.pypython
app = Flask(__name__)
app.config["DEBUG"] = os.environ.get("APP_ENV") == "development"
CORS(app, origins=["https://app.example.com"], supports_credentials=True)

@app.after_request
def set_headers(resp):
    resp.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
    resp.headers["X-Content-Type-Options"] = "nosniff"
    resp.headers["Content-Security-Policy"] = "default-src 'self'"
    return resp
docker-compose.ymlyaml
services:
  db:
    image: postgres:16
    expose:
      - "5432"                 # acessível apenas por outros serviços da rede
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
bucket.tfhcl
resource "aws_s3_bucket_public_access_block" "assets" {
  bucket                  = aws_s3_bucket.assets.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

Prove a correção

A má configuração se verifica escaneando, não lendo código. Rode um scanner de configuração no CI contra e imagens, e rode uma pequena verificação contra o app implantado. O teste quebra o build quando um padrão seguro regride.

ci-checks.shbash
# 1. código de infraestrutura: falhar em recursos mal configurados
checkov -d infra/ --quiet --compact

# 2. imagem de contêiner: falhar em achados HIGH/CRITICAL
trivy image --exit-code 1 --severity HIGH,CRITICAL registry.example.com/app:$GIT_SHA

# 3. app implantado: os headers obrigatórios devem estar presentes
curl -sI https://staging.example.com | grep -qi '^strict-transport-security:' || exit 1
curl -sI https://staging.example.com | grep -qi '^content-security-policy:' || exit 1
test_config.py (pytest)python
def test_debug_is_off_in_production(monkeypatch):
    monkeypatch.setenv("APP_ENV", "production")
    assert create_app().config["DEBUG"] is False

def test_cors_does_not_allow_any_origin(client):
    resp = client.options("/api/me", headers={"Origin": "https://evil.example"})
    assert resp.headers.get("Access-Control-Allow-Origin") != "*"

Checklist

  • Um processo de hardening repetível e automatizado para todos os ambientes; nada de servidores ajustados à mão.
  • Remova recursos não usados, apps de exemplo, contas padrão e portas abertas.
  • Envie os headers de segurança aplicáveis (HSTS, CSP, X-Content-Type-Options, proteção contra frames).
  • Mostre erros genéricos aos usuários; envie os detalhes para os logs, não para a resposta.
  • Revise permissões de nuvem e exposição de armazenamento continuamente, não uma só vez.
  • Trate a configuração como código: revisada, versionada, escaneada.
OWASP Top 10A lista de referência mais famosa de riscos de segurança em aplicações web (A01 acesso quebrado, A02 falhas criptográficas, A03 injeção...), revisada a cada alguns anos pela comunidade OWASP. É um mapa educacional de categorias de risco — não um checklist de ferramenta nem uma certificação.ver no glossário →CORScompartilhamento de recursos entre origensUm mecanismo do navegador que permite a um servidor dizer quais outras origens podem ler suas respostas. Uma origem curinga combinada com credenciais é uma má configuração.ver no glossário →IaCinfrastructure as codeDescrever infraestrutura em arquivos versionados (Terraform, Ansible). Dá revisão, histórico e testes à configuração, mas replica erros em escala se não for escaneada.ver no glossário →

conexões no mapa

atualizado em 14/10/2026 · fontes para aprofundar · reportar erro

em outros domínios

teste o que entendeu

Carregando perguntas…