pular para o conteúdo
voltar ao mapa
conceito
etapa: design
3 min de leitura

A06 Insecure Design

Uma implementação perfeita de um design ruim continua sendo uma vulnerabilidade. A segurança precisa ser pedida antes da primeira linha de código, como requisito, e não encontrada depois como um bug.

OWASP Threat DragonMicrosoft Threat Modeling ToolSTRIDEOWASP ASVSOWASP SAMMabuse-case workshops

O que é

Insecure design é uma fraqueza em como uma funcionalidade é concebida: um controle ausente, uma suposição de confiança que não se sustenta ou um fluxo de negócio que pode ser abusado exatamente como foi escrito. Difere de um bug de implementação. Um bug é código que não faz o que o design diz; um design inseguro é código que faz exatamente o que o design diz, e o problema é o design.

O :2025 o mantém como A06. A correção é mais uma prática do que um patch: faça threat modeling cedo, escreva casos de abuso ao lado dos casos de uso e reutilize padrões de design seguro.

Como o ataque funciona

  • Uma redefinição de senha que pergunta "qual foi o seu primeiro bichinho?" permite que qualquer pessoa capaz de pesquisar sobre você assuma a conta.
  • Um endpoint de cupom sem limite por cliente permite que um script esgote a promoção em minutos.
  • Um fluxo de venda de ingressos que reserva assentos sem expiração permite que um bot bloqueie o local inteiro.
  • Um checkout em várias etapas que confia no preço enviado na última etapa permite que os usuários paguem o que quiserem.
  • Um formulário "esqueci meu usuário" que revela se um e-mail está cadastrado permite a enumeração de contas.

Design vulnerável, em código

O código abaixo é limpo e não tem bugs. O design permite que um atacante teste códigos promocionais sem limite e confia em um preço fornecido pelo cliente.

checkout.pypython
@app.post("/api/checkout")
@login_required
def checkout():
    data = request.get_json()
    total = data["total"]                       # preço decidido pelo cliente
    code = data.get("promo")
    if code and Promo.query.filter_by(code=code).first():
        total = total * 0.5                     # tentativas ilimitadas, reuso ilimitado
    return charge(current_user, total)

A correção

Projete os controles dentro do fluxo: o servidor calcula o preço a partir de dados confiáveis, um código promocional é de uso único por conta e as tentativas sofrem , e os limites são regras de negócio escritas antes de codificar. O "enumerar códigos promocionais" gerou o requisito.

checkout.pypython
@app.post("/api/checkout")
@login_required
@rate_limit("10/minute", key=lambda: current_user.id)
def checkout():
    cart = Cart.for_user(current_user)           # fonte da verdade no servidor
    total = cart.total()                         # os preços vêm do catálogo
    code = request.get_json().get("promo")
    if code:
        promo = Promo.redeem(code, user=current_user)   # uso único por usuário, atômico
        if promo is None:
            abort(400, "invalid promo")
        total = promo.apply(total)
    return charge(current_user, total)

Prove a correção

Um controle de design precisa de um teste escrito a partir do caso de abuso, não do caminho feliz. Cada caso de abuso que você listou vira um teste automatizado: o cliente não pode definir o preço, um código não pode ser reutilizado e uma rajada de tentativas é limitada.

test_checkout_abuse.py (pytest)python
def test_client_cannot_choose_the_price(client, alice, cart_of_100):
    r = client.post("/api/checkout", json={"total": 1}, auth=alice)
    assert charged_amount(r) == 100

def test_promo_is_single_use(client, alice, promo_half_off):
    assert client.post("/api/checkout", json={"promo": promo_half_off}, auth=alice).status_code == 200
    assert client.post("/api/checkout", json={"promo": promo_half_off}, auth=alice).status_code == 400

def test_promo_guessing_is_throttled(client, alice):
    codes = [client.post("/api/checkout", json={"promo": f"TRY{i}"}, auth=alice).status_code for i in range(30)]
    assert 429 in codes
abuse-cases.md (fica ao lado das user stories)markdown
Como atacante, quero adivinhar códigos promocionais para obter descontos que não deveria.
  -> controle: rate limit por conta e por IP, códigos longos e aleatórios, uso único
  -> teste: test_promo_guessing_is_throttled

Como cliente, quero alterar o preço na requisição para pagar menos.
  -> controle: o preço é calculado no servidor a partir do catálogo
  -> teste: test_client_cannot_choose_the_price

Checklist

  • Faça threat modeling de novas funcionalidades antes de construí-las: o que estamos protegendo, quem ataca, o que os detém ( é um bom começo).
  • Escreva casos de abuso ao lado dos casos de uso e transforme cada um em um requisito e um teste.
  • Reutilize padrões comprovados (autenticação, rate limiting, gestão segura de sessão) em vez de inventá-los.
  • Separe tenants e níveis de confiança por design; limite o uso de recursos por usuário.
  • Use um padrão como o para transformar "seja seguro" em requisitos verificáveis.
  • Revise o modelo quando o design mudar, não uma vez por ano.
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 →Rate limitingLimite de requisições por entidade e janela de tempo. A escolha da chave (IP, conta, token, ASN) pesa tanto quanto o valor do limite.ver no glossário →Caso de abusoUma história de usuário escrita do lado do atacante. Cada uma gera um requisito e um teste.ver no glossário →STRIDEMnemônico de seis categorias de ameaça (Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege) usado como checklist ao percorrer um diagrama de fluxo de dados.ver no glossário →OWASP ASVSverification standardApplication Security Verification Standard: checklist verificável, em três níveis de rigor, para auditar uma aplicação ou contratar auditoria. Onde o Top 10 ensina, o ASVS audita.ver no glossário →

conexões no mapa

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

em outros domínios

Estude antes

teste o que entendeu

Carregando perguntas…