Checklist — pen test autenticação (Fase 4 · P4-06)
Revisão de segurança do refactor auth (MVP1 Modo A). Alinhado aos riscos do plano AUTH-01 §20 e à Parte B §B10.
Público: QA, segurança, DevOps antes de homologação/produção.
Ambiente típico: QAS com .env-dev ou espelho do cliente.
Status: P4-06 concluído (2026-07-07) — smoke 18/18 + aceite MANUAL.
Resultados: 2026-07-01 · 2026-07-07
Como usar
- Marque OK, FALHA, N/A ou MANUAL em cada item.
- Itens MANUAL exigem browser, IdP real ou revisão de infra (gateway, logs).
- Falhas críticas bloqueiam gate F4; médias entram no backlog com prazo.
- Reexecute após mudanças em
WebSecurityConfig, external-login, gateway ou AUTH_TOKEN_SECRET.
Severidade: C = crítica · A = alta · M = média · B = baixa
1. Superfície de ataque e rotas públicas
| ID |
Teste |
Severidade |
Esperado |
☐ |
| R-01 |
GET /ecosif-masterdata/user sem Authorization |
C |
401 |
OK |
| R-02 |
GET /ecosif-moviments/... sem token |
C |
401 (se serviço no ar) |
|
| R-03 |
POST /ecosif-auth/api/auth/signin sem token |
B |
200 ou 401 (credenciais) — rota pública por design |
|
| R-04 |
POST /ecosif-auth/api/auth/external-login sem token ECOSIF |
B |
400/401 — rota pública; valida body/token IdP |
|
| R-05 |
GET /ecosif-auth/actuator/health sem token |
B |
200 UP — health público |
OK |
| R-06 |
POST /ecosif-auth/api/auth/signin-azure |
A |
404 (removido MVP3) |
OK |
| R-07 |
Rotas admin Angular /dashboard sem JWT no browser |
C |
Redirect /login (AuthGuard) |
OK |
| R-08 |
Swagger /ecosif-auth/swagger-ui/ em produção |
M |
Desabilitado ou restrito por rede |
MANUAL |
2. JWT ECOSIF — integridade e ciclo de vida
| ID |
Teste |
Severidade |
Esperado |
☐ |
| J-01 |
Token válido de signin → API protegida |
C |
200 |
OK |
| J-02 |
Token com assinatura adulterada (char no meio do JWT) |
C |
401 |
OK |
| J-03 |
Token alg:none ou payload forjado |
C |
401 |
OK |
| J-04 |
Token expirado (exp no passado) |
C |
401 |
|
| J-05 |
Token emitido com outro AUTH_TOKEN_SECRET |
C |
401 |
|
| J-06 |
Authorization: Bearer vazio / Bearer null |
A |
401 |
OK |
| J-07 |
Refresh GET /user com token válido retorna novo JWT |
A |
200 + novo accessToken |
OK |
| J-08 |
GET /user com token expirado |
A |
401 + logout no Angular |
OK |
| J-09 |
Claim sub de outro usuário (token re-assinado se possível) |
C |
401 ou dados do sub do token apenas |
|
| J-10 |
JWT Microsoft/Google enviado direto na API (Modo A) |
A |
401 — só JWT ECOSIF |
|
3. Login local (signin)
| ID |
Teste |
Severidade |
Esperado |
☐ |
| S-01 |
Credenciais inválidas |
A |
401 — mensagem genérica |
OK |
| S-02 |
Usuário inativo |
A |
401 |
|
| S-03 |
signin com "azure": true |
A |
400 — sem bypass Azure |
OK |
| S-04 |
Body vazio / JSON malformado |
M |
400 |
|
| S-05 |
SQLi no username (' OR '1'='1) |
C |
401 — sem erro SQL/stack |
OK |
| S-06 |
Resposta não expõe se usuário existe vs senha errada |
M |
Mensagem uniforme |
|
| S-07 |
Senha não aparece em logs do auth |
C |
Revisar logs |
MANUAL |
| S-08 |
Rate limit em external-login (P4-04) |
M |
HTTP 429 após limite por IP |
OK |
4. Login externo (external-login)
| ID |
Teste |
Severidade |
Esperado |
☐ |
| E-01 |
Token IdP inválido / string aleatória |
C |
401 |
OK |
| E-02 |
Token expirado (jwt.ms ou fixture) |
C |
401 |
OK |
| E-03 |
aud incorreta (token de outro client-id) |
C |
401 |
OK |
| E-04 |
iss incorreto |
C |
401 |
OK |
| E-05 |
provider vazio ou não suportado |
A |
400 |
OK |
| E-06 |
provider: GOOGLE com ECOSIF_AUTH_PROVIDER=AZURE |
A |
400 |
OK |
| E-07 |
Login só com username sem token (legado) |
C |
400/401 — sem bypass |
|
| E-08 |
ECOSIF_AUTH_AUTO_PROVISION=false + usuário inexistente |
A |
404 |
OK |
| E-09 |
Token IdP de outro tenant (ECOSIF_AZURE_ALLOWED_TENANTS se ativo) |
C |
401 |
N/A MVP1 |
| E-10 |
Logs não contêm token completo |
C |
Só provider, sub, event |
OK |
| E-11 |
Resposta não vaza token IdP — só JWT ECOSIF |
A |
Body sem id_token Microsoft |
|
5. Sessão e frontend (Angular)
| ID |
Teste |
Severidade |
Esperado |
☐ |
| F-01 |
JWT armazenado — não em cookie sem HttpOnly crítico |
M |
localStorage / config atual documentada |
OK |
| F-02 |
Falha refresh → logout e redirect /login |
A |
Sem reutilizar token expirado |
OK |
| F-03 |
MSAL não envia token Microsoft nas APIs (Modo A) |
C |
Só JWT ECOSIF no interceptor |
OK |
| F-04 |
external-login ignorado no retry 401 do interceptor |
A |
Sem loop infinito |
OK |
| F-05 |
Auth health: login desabilitado se auth down |
M |
Botões disabled + alerta |
OK |
| F-06 |
CORS: origem não permitida bloqueada |
A |
Preflight / erro CORS |
OK |
6. Microsserviços e defense in depth
| ID |
Teste |
Severidade |
Esperado |
☐ |
| M-01 |
oauth2Login() desativado nos 5 backends Java |
A |
Sem redirect OAuth server-side — grep + smoke §5 |
OK |
| M-02 |
Mesmo AUTH_TOKEN_SECRET em auth + masterdata + … |
C |
Token de auth válido em masterdata |
OK |
| M-03 |
ECOSIF_JWT_SUBJECT_CLAIM consistente (refresh /user) |
A |
Mesmo sub após refresh |
OK |
| M-04 |
Acesso direto à porta do serviço (bypass nginx) |
M |
Ainda exige JWT — não confiar só no proxy |
|
| M-05 |
Gateway rejeita sem JWT (se Traefik/APIM configurado) |
C |
401 na borda |
OK |
7. Integrações e legado
| ID |
Teste |
Severidade |
Esperado |
☐ |
| I-01 |
ecosif-automations signin → APIs |
A |
200 em fluxo feliz |
✅ scripts/regression-auth-signin.sh |
| I-02 |
signin exposto na internet sem restrição |
M |
VPC / allowlist / rate limit em prod |
MANUAL |
| I-03 |
Bundle Angular sem signin-azure |
A |
grep ecosif-angular/src + smoke §5 |
OK |
8. Segredos e configuração (§20 — riscos)
| ID |
Teste |
Severidade |
Esperado |
☐ |
| C-01 |
AUTH_TOKEN_SECRET ≥ 48 chars (HS512) |
C |
.env produção |
OK |
| C-02 |
Secret não commitado no repositório |
C |
grep em histórico git |
OK |
| C-03 |
ECOSIF_AZURE_CLIENT_ID / tenant não são secrets — OK expor no front |
B |
Documentado |
OK |
| C-04 |
Redirect URI no Entra = domínio real do deploy |
A |
Sem open redirect |
OK |
| C-05 |
TLS em produção (HTTPS only) |
C |
Sem login em HTTP público |
OK |
9. Riscos §20 — verificação de mitigação
| Risco (plano §20) |
Mitigação verificada |
☐ |
| Cliente exige access token MS no gateway |
Modo B documentado (MVP5) — N/A Modo A |
N/A |
| Groups truncadas Azure |
MVP4 Graph overage — N/A homolog |
N/A |
| Quebra automations |
I-01 regressão |
OK |
Inconsistência sub após refresh |
J-07, M-03 |
OK |
| CORS / redirect URI errado |
F-06, C-04 |
OK |
| Múltiplos IdPs |
MVP5 P7-D — um IdP/tenant hoje |
N/A |
Comandos rápidos (smoke automatizado)
# Na raiz do monorepo, com stack docker ativa:
BASE=http://localhost
AUTH=$BASE/ecosif-auth
MD=$BASE/ecosif-masterdata
# J-02 adulterar assinatura (meio do token; sufixo pode ser ignorado pelo parser)
TOKEN=$(curl -s -X POST $AUTH/api/auth/signin -H 'Content-Type: application/json' \
-d '{"username":"admin","password":"***"}' | jq -r .accessToken)
TAMPERED="${TOKEN:0:100}x${TOKEN:101}"
curl -s -o /dev/null -w '%{http_code}\n' $MD/user -H "Authorization: Bearer $TAMPERED"
# E-01 token inválido
curl -s -o /dev/null -w '%{http_code}\n' -X POST $AUTH/api/auth/external-login \
-H 'Content-Type: application/json' \
-d '{"provider":"AZURE","token":"invalid","tokenType":"ID_TOKEN"}'
Script completo: ecosif-auth/scripts/pen-test-auth-smoke.sh
Variáveis opcionais: ECOSIF_AUTH_BASE_URL, ECOSIF_MASTERDATA_BASE_URL (quando auth e masterdata não estão no mesmo host/porta — ex.: auth IntelliJ em :8081, masterdata via Traefik em :80).
ECOSIF_AUTH_BASE_URL='http://localhost:8091' \
ECOSIF_MASTERDATA_BASE_URL='http://localhost' \
ECOSIF_SIGNIN_PASSWORD='***' \
./ecosif-auth/scripts/pen-test-auth-smoke.sh
Critério de aceite P4-06
- [x] Checklist preenchido em QAS (ou local documentado)
- [x] Zero falhas críticas (C) abertas
- [x] Falhas A/M com ticket ou aceite explícito
- [x] Resultado arquivado em
pen-test-checklist-auth-resultado-YYYY-MM-DD.md
Referências