Toda vaga de Dev Java sênior em 2026 pede experiência com segurança de APIs REST. Mas quando o entrevistador pergunta "você já trabalhou com um bypass de autorização?", a maioria responde com teoria. Os candidatos que chegam com um caso real, com código, exploit e fix, são os que passam para a próxima fase.
O CVE-2026-39852 do Quarkus é exatamente esse caso. Uma vulnerabilidade crítica que afeta todas as versões antes de 3.34.7 (LTS) e 3.35.2 (main): um atacante acessa /api/admin;bypass e toda a sua configuração de @RolesAllowed vira pó, com o CI verde e os testes passando normalmente.
Neste artigo você vai entender como o exploit funciona na prática, por que a arquitetura do RESTEasy Reactive permite isso, como corrigir em 1 linha e, principalmente, como usar esse conhecimento numa entrevista sênior de Java em 2026. Bora?
O que é o CVE-2026-39852 e por que ele é diferente
A maioria dos CVEs que aparece no feed são sobre dependências transitivas: uma lib de parsing de JSON com CVSS 9.8, você atualiza o pom.xml, fim de papo. O CVE-2026-39852 é diferente porque a falha está na arquitetura do próprio framework, no ponto de contato entre a camada de segurança HTTP e o roteador RESTEasy Reactive.
Publicado em 04 de maio de 2026 com releases emergenciais para todas as streams suportadas do Quarkus, o CVE expõe um path normalization bypass: a camada de segurança HTTP avalia o path da requisição antes do RESTEasy Reactive normalizá-lo. E é nessa janela que o ataque acontece.
Numa aplicação Quarkus com o endpoint abaixo, você espera que qualquer chamada a /api/admin exija a role "admin":
@Path("/api/admin")
@RolesAllowed("admin")
public class AdminResource {
@Inject
UserService userService;
@GET
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
public Response listUsers() {
return Response.ok(userService.findAll()).build();
}
}
Com Quarkus abaixo de 3.34.7, a chamada abaixo retorna HTTP 200 com a lista completa de usuários, sem autenticação:
curl -s "http://localhost:8080/api/admin;qualquercoisa/users"
# Resultado: ["Este endereço de e-mail está sendo protegido de spambots. Você precisa habilitar o JavaScript para visualizá-lo. ", "Este endereço de e-mail está sendo protegido de spambots. Você precisa habilitar o JavaScript para visualizá-lo. ", ...]
# Sem token. Sem role admin. Acesso completo.
Como Tech Leader, já revisei dezenas de auditorias de segurança onde esse tipo de bypass foi classificado como "improvável em produção". O CVE-2026-39852 prova que improvável não é impossível, e no mundo de microsserviços internos (sem WAF na frente), a superfície de exposição é real.
Como o bypass funciona por dentro
Pensa no fluxo de uma requisição HTTP no Quarkus assim: pensa num porteiro de boate com uma lista de VIPs. O ponto do CVE é que o porteiro (segurança HTTP) lê um endereço escrito de jeito diferente do que a recepção (RESTEasy) vai processar depois.
O fluxo técnico acontece em duas etapas:
- Etapa 1 (Segurança HTTP): recebe o path
/api/admin;qualquercoisa/userse verifica se há política de autorização para esse path. Como a política está registrada como/api/admin/**, e o path com o ponto-e-vírgula não bate exatamente, a requisição é liberada como pública. - Etapa 2 (RESTEasy Reactive): recebe o path já liberado pela segurança, normaliza
/api/admin;qualquercoisa/userspara/api/admin/users(o ponto-e-vírgula e o que vem depois dele é removido pelo padrão de URIs RFC 3986), encontra o handler e executa a lógica.
O resultado: a segurança verificou um path, o roteador roteou para outro. A falha fica na lacuna entre as duas camadas, e o @RolesAllowed nunca é consultado porque a camada HTTP já liberou a requisição antes de chegar no método Java.
Versões afetadas:
- Todas as versões LTS abaixo de 3.34.7
- Todas as versões main abaixo de 3.35.2
- Qualquer app Quarkus que usa RESTEasy Reactive com políticas de segurança HTTP (
quarkus.http.auth.permission.*) é vulnerável
Como reproduzir e verificar a vulnerabilidade
Antes de aplicar o patch, vale confirmar se a sua versão é realmente afetada. Crie um endpoint de teste isolado:
package com.empresa.api;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.*;
@Path("/security-test")
public class SecurityTestResource {
@GET
@Path("/protected")
@RolesAllowed("admin")
@Produces(MediaType.APPLICATION_JSON)
public Response protectedEndpoint() {
return Response.ok("ACESSO CONCEDIDO").build();
}
}
No application.properties:
quarkus.http.auth.permission.protected-role.paths=/security-test/*
quarkus.http.auth.permission.protected-role.policy=authenticated
Teste sem token e depois com o bypass:
# Teste 1: sem token (deve retornar 401)
curl -s -o /dev/null -w "%{http_code}" "http://localhost:8080/security-test/protected"
# Resultado esperado: 401
# Teste 2: com bypass (versão vulnerável retorna 200!)
curl -s -o /dev/null -w "%{http_code}" "http://localhost:8080/security-test;cve/protected"
# Versão vulnerável: 200 (bypass funcionou)
# Versão corrigida: 401 (bypass bloqueado)
Se o segundo teste retornou 200 na sua versão, sua API está vulnerável agora.
O fix: como corrigir em 1 linha
A correção é atualizar o Quarkus BOM para a versão com o patch. No pom.xml:
<!-- Antes: versão vulnerável -->
<dependency>
<groupId>io.quarkus.platform</groupId>
<artifactId>quarkus-bom</artifactId>
<version>3.34.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Depois: versão corrigida -->
<dependency>
<groupId>io.quarkus.platform</groupId>
<artifactId>quarkus-bom</artifactId>
<version>3.34.7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Para projetos usando Quarkus CLI:
# Atualizar para a versão LTS corrigida
quarkus update --quarkus-version=3.34.7
# Ou para a stream main mais recente
quarkus update --quarkus-version=3.35.2
Após a atualização, rode o teste de verificação de novo. O segundo teste com bypass deve retornar 401.
Uma coisa importante: se a sua aplicação usa quarkus.http.auth.permission.* para políticas de segurança baseadas em paths (que é a abordagem recomendada pelo Quarkus para microsserviços), você é afetado. Se usa apenas @RolesAllowed sem as políticas HTTP de path, o impacto é menor, mas o upgrade ainda é recomendado.
Impacto em produção e o que muda no dia a dia
Pensa na superfície real de exposição: uma API de microsserviço interna, sem WAF, acessível via Kubernetes Service DNS interno. Desenvolvimento, QA, staging, todos na mesma rede. Qualquer container comprometido pode chamar /api/admin;x/users e vazar dados sem deixar rastro no log de autorização, porque a autorização nunca foi checada.
Para times com práticas de segurança maduras, a checklist muda:
- Pentest e red team: adicionar testes de path normalization bypass em todos os endpoints protegidos
- Dependabot / Renovate: configurar alertas para minor versions do Quarkus, não só major
- Revisar policies de path: paths com wildcards
/**são mais seguros que paths exatos
Para o Spring Boot, o Spring Security lida com isso na camada do DispatcherServlet. Quem trabalha com os dois frameworks precisa entender essas diferenças arquiteturais, porque elas aparecem exatamente em perguntas de entrevista sênior. Para mais detalhes sobre como o Spring Security processa filtros de segurança, veja como funciona a cadeia de filtros do Spring Security.
Se você quer entender as diferenças de performance e segurança entre Quarkus e Spring Boot em cenários reais de produção, recomendo também a análise de Quarkus vs Spring Boot em 2026 que publicamos anteriormente.
Por que esse CVE vai cair na sua entrevista
Vaga de Dev Java sênior em 2026 tem três pilares de segurança que aparecem em toda entrevista técnica: autenticação/autorização (JWT, OAuth2), injeção (SQL, command injection) e, cada vez mais, vulnerabilidades de framework. É nesse terceiro pilar que o CVE-2026-39852 se encaixa.
Por quê? Porque ele exige que o candidato entenda:
- O fluxo de uma requisição HTTP dentro do framework
- A diferença entre avaliação de segurança antes e depois da normalização de path
- Como escrever um teste de penetração básico
- Como estruturar um processo de resposta a CVE em produção
As perguntas que aparecem em entrevista sênior sobre esse tema:
- "Você já precisou responder a um CVE em produção? Como foi o processo?"
- "Como você verifica se um endpoint REST está realmente protegido além de checar a anotação no código?"
- "Qual a diferença entre segurança implementada no framework HTTP e segurança implementada no código da aplicação?"
Se você reproduziu o CVE-2026-39852 no ambiente local, escreveu o teste de verificação e aplicou o patch, você tem respostas concretas para as três perguntas. Isso te separa de 90% dos candidatos que falam de segurança de forma abstrata.
Perguntas Frequentes
O CVE-2026-39852 afeta o Spring Boot?
Não diretamente. O Spring Security processa a autorização após a normalização do path pelo DispatcherServlet, eliminando esse vetor específico. Mas técnicas similares de path manipulation existem em outros contextos. Fique atento a CVEs do Spring Security separadamente.
Preciso reiniciar o serviço após o update do Quarkus?
Sim. A atualização do Quarkus BOM requer rebuild e redeploy da aplicação. Não é possível aplicar patches de segurança do Quarkus em hot-deploy. Planeje uma janela de manutenção ou use rolling update no Kubernetes para zero downtime.
Se eu uso Quarkus com GraalVM Native Image, o processo é o mesmo?
Sim. Atualize a versão do Quarkus BOM, execute o rebuild com mvn package -Pnative e redeploy. A imagem native já incluirá a versão corrigida do RESTEasy Reactive.
Como saber se algum endpoint foi acessado via bypass antes da correção?
Busque nos logs de acesso por requisições com ponto-e-vírgula na URL: grep ";" access.log | grep -v "JSESSIONID". No Kubernetes, filtre nos logs do ingress/service mesh. Requisições legítimas raramente contêm ponto-e-vírgula na URI.
Takeaways e próximos passos
- O bypass é real e reproduzível: um ponto-e-vírgula na URL contorna todo o
@RolesAllowedem versões vulneráveis do Quarkus. CI verde não garante segurança. - O fix é 1 linha no pom.xml: atualizar para Quarkus 3.34.7 (LTS) ou 3.35.2 (main) fecha o CVE imediatamente. Verifique com o teste de bypass antes e depois.
- É material de entrevista sênior: entender a raiz arquitetural diferencia você dos candidatos que só sabem a definição do CVE.
Você já usa Quarkus em produção? Sua stack tem esse CVE presente? Conta nos comentários como está sendo na prática e se encontrou alguma variação no comportamento.
Na próxima semana vou cobrir a diferença arquitetural completa de segurança entre Quarkus e Spring Boot. Enquanto isso, veja como implementar OAuth2 com JWT no Spring Security para comparar a abordagem.