0019 — Bumps comum-web 0.5.0 + seguranca 0.4.0: dropa handlers, dedup AuthSupport, adota CSRF de sessão¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-08-19 · Decidido em: 2026-08-19
Contexto. As libs da casa evoluíram cobrindo o que o app ainda espelhava localmente. A
xadm-comum-web 0.5.0 fez o UnifiedErrorResponseProcessor logar no ponto único (5xx em
ERROR com a causa-raiz → pega o SentryAppender; 4xx em DEBUG) — feedback §6 do ciclo do
0017 que landou na lib. A xadm-seguranca 0.4.0 extraiu o
contrato byte-idêntico do AuthSupport (constantes de atributo/cookie + isHttps/
deveRecusarAnonimo) e trouxe o CsrfTokens (token CSRF derivado da sessão, exposto pelo
SessionAuthenticationFetcher no atributo auth.csrf). É a continuação da iniciativa libs+contrato
(0017/0018).
Decisão.
- Dropar
ServerExceptionHandler/UnauthorizedExceptionHandler. Com o log no processor da lib, os@ExceptionHandlerdedicados viraram recópia.ServerException/UnauthorizedExceptionpassaram aextends HttpStatusException implements PortadoraDeProblema(carregam status +codede máquina); oUnifiedErrorResponseProcessorrenderiza oproblem+jsone loga o 5xx→Sentry. Corpo byte-idêntico (o default PT de mensagem nula migrou para dentro da exceção); provado porExceptionRenderingIT. Nuance aceita: 401 loga emDEBUG(eraWARNno handler) — erro de cliente, esperado.GlobalExceptionHandler(página HTML de erro p/ browser) eViewRejectionHandler(policy de auth) ficam — a lib só emiteproblem+json. - Dedup do
AuthSupportlocal. Constantes (AUTH_EMAIL_ATTR/AUTH_NAME_ATTR/AUTH_CSRF_ATTR/SESSION_COOKIE) +isHttpsvêm da lib (br.com.xadm.comum.seguranca.AuthSupport). A whitelist de views (policy de rota do app) saiu para uma classe própriaViewWhitelist— mesmo nome de conceito ≠ mesma decisão. OdeveRecusarAnonimolocal (código morto) foi removido. - Adotar CSRF de sessão nas escritas das views.
CsrfTokens.verifyfoi dobrado noUiProductionGuard(assertCrudWriteAllowed(csrf)/assertDebugAllowed(csrf)) — o mesmo call-site que todo@Postde escrita já invocava.GlobalViewModelexpõecsrfToken(do atributoauth.csrf); todo form de escrita (form.htmlsave +list.htmldeletar/restaurar + os POST JS do/debug) renderiza o campo oculto_csrf. Overifyé no-op em dev/test (auth em bypass, o atributoauth.csrfnão é setado) e exige o token em produção (403 em divergência). Provado porCsrfProtectionIT(sem token → 403, token errado → 403, token correto → passa). O login CSRF (double-submitxadm_login_csrfdoLoginController, fase pré-sessão) é outro mecanismo e fica como está. - Corrige gap pré-existente de guard. 5 handlers de escrita (
ItensLote.delete,ItensPed.save,NotaCompl.delete,TbpcoEst.save,Veiculos.save) não chamavam oUiProductionGuard— aViewSecurityRulejá barrava anônimo em prod, mas a defesa-em-profundidade faltava e sem ela não haveria verificação CSRF nesses endpoints. Agora todos os 42 POST de escrita das entidades (14 × 3) - os 3 do
/debugpassam pelo guard com CSRF.
Consequências. ./gradlew check sobe com comum-web:0.5.0 + seguranca:0.4.0. Correção de
segurança/erro na casa chega ao app por bump. A superfície de escrita das views deixou de ser
CSRF-vulnerável. A PortadoraDeProblema é o seam de erro do app daqui pra frente (novas exceções de
domínio só a implementam).
Fora de escopo: as libs em si (repo xadm-commons); CSRF do endpoint GET /propriedades/sync-nome-curto
(escrita disparada por GET — anomalia pré-existente, sem form/token; fica para um saneamento próprio
do verbo).