Architecture Security JWT SQL Isolation
Blueprint de Segurança

Autenticação Stateless Segura e Prevenção de IDOR

Uma análise arquitetural das três camadas complementares que constituem uma aplicação web verdadeiramente segura: identidade via JWT stateless, transporte via Cookie HttpOnly, e autorização final ao nível da query SQL. Cada camada resolve um problema distinto — nenhuma substitui as outras.

Princípio central Autenticação, transporte e autorização são domínios distintos. Resolver um não resolve os outros. Esta separação é a raiz de muitas vulnerabilidades em sistemas que consideram "estar autenticado" suficiente.

A Holy Trinity of Web Security

A arquitetura que este repositório defende assenta em três garantias complementares. Cada uma é necessária; nenhuma é suficiente isoladamente.

Módulo 1 · JWT
A Identidade — Stateless

O servidor não guarda sessões em RAM. A identidade e os privilégios viajam num token assinado matematicamente, verificável por qualquer instância horizontal sem consultar um store central.

Módulo 2 · Cookie
O Transporte — HttpOnly + Secure

O JWT nunca é exposto ao JavaScript. Viaja dentro de um Cookie com HttpOnly (bloqueia leitura por JS) e Secure (exige HTTPS). O browser anexa-o automaticamente a cada pedido.

Módulo 3 · SQL
O Cadeado Final — Isolamento Lógico

Autenticação prova quem é o utilizador, não o que lhe pertence. Todas as queries filtram por resource_id e owner_id para neutralizar IDOR na raiz.

O Problema: IDOR em Detalhe

Insecure Direct Object Reference (IDOR) ocorre quando um sistema confia num identificador fornecido pelo cliente sem verificar se o recurso pertence ao utilizador autenticado:

-- Pedido: GET /api/accounts/5
-- Utilizador autenticado: user 99. O servidor não verifica a posse.

SELECT * FROM accounts WHERE id = 5;

-- Atacante muda 5 → 6 na URL: lê dados de outro utilizador sem qualquer erro.
Vulnerabilidade O token confirma "este é o utilizador 99". A query devolve o que for pedido — não verifica posse. Qualquer utilizador autenticado pode enumerar recursos alheios apenas incrementando o ID.

A Solução: Dois Filtros, Sempre

O backend extrai o user id diretamente do JWT no cookie seguro e projeta-o como condição obrigatória na query. O cliente nunca controla o owner_id:

-- Pedido: GET /api/accounts/6
-- JWT no cookie → user_id = 99 (extraído pelo servidor, nunca pelo cliente)

SELECT * FROM accounts
WHERE  id       = 6
  AND  owner_id = 99;

-- Conta 6 não pertence ao user 99 → 0 resultados → 404 Not Found
Porque 404 e não 403? 403 Forbidden confirma ao atacante que o recurso existe mas não lhe pertence. 404 Not Found não revela essa informação — é a resposta mais segura contra enumeração de recursos.

Fluxo Completo de um Pedido Seguro

1
Autenticação inicial (Login)

Credenciais validadas. Servidor emite JWT via Set-Cookie: access_token=...; HttpOnly; Secure; SameSite=Lax. O token nunca toca no JavaScript.

2
Pedido autenticado

Browser anexa o cookie automaticamente. JavaScript não tem acesso ao valor do token — não existe em localStorage nem em variáveis JS.

3
Validação da assinatura no servidor

Servidor extrai o cookie, valida a assinatura criptográfica e extrai o sub (user id). Qualquer falha → 401 Unauthorized imediato.

4
Query com isolamento lógico

O user id extraído do JWT é injetado como owner_id na query. A autorização é estrutural — não uma verificação opcional após a leitura.

5
Resposta ou negação

Resultados encontrados → dados devolvidos. Zero resultados → 404 Not Found, sem revelar a existência do recurso.

Comparação das Três Camadas

CamadaPergunta que respondeO que protegeO que não resolve sozinha
JWTQuem é este utilizador?Identidade verificável, escalabilidade horizontalExposição browser, CSRF, IDOR
Cookie HttpOnlyComo o token viaja em segurança?Mitigação de XSS, transporte forçado por HTTPSAutorização ao recurso, CSRF completo
Query owner_idEste objeto pertence a quem autenticou?Posse de recursos, anti-enumeraçãoAutenticação de pedidos