Dapr corrige bypass de ACL que a correção de abril deixou pela metade
Em 9 de outubro de 2026 o Dapr lançou patches simultâneos pras duas branches que mantém hoje — v1.18.6 e v1.17.16 — cobrindo quatro falhas de segurança em service invocation e workflows. A mais importante das quatro não é uma CVE nova: é o resto de uma CVE de abril que ninguém tinha fechado de verdade.
Dapr é projeto Graduated do CNCF desde novembro de 2024, no mesmo nível de maturidade de Kubernetes, Prometheus e Envoy. Isso não quer dizer que bug de autorização para de acontecer — quer dizer que quando acontece, geralmente sai documentado, com CVE, patch pra toda branch suportada e aviso claro de quem foi afetado. Esse patch é exatamente esse caso.
O que ficou pela metade em abril
Em 16 de abril de 2026 o Dapr publicou a GHSA-85gx-3qv6-4463 (CVE-2026-41491, CVSS 8.1 alta): a política de controle de acesso de service invocation validava uma versão normalizada do método chamado, mas o dispatch de fato roteava o método bruto. A normalização usada na ACL (via purell.NormalizeURLString) decodificava %XX, resolvia ../ e removia # e ? antes de comparar contra a policy — então um método como admin%2F..%2Fpublic passava a ACL como public, mas chegava no app de destino como admin/../public. Quem definia a policy pensando estar bloqueando /admin podia estar, sem saber, liberando passagem pra lá via uma string cuidadosamente codificada.
A correção de abril (nas versões 1.15.14, 1.16.14 e 1.17.5) resolveu a parte de ../ decodificado e de #/? escondidos. O que ela não cobriu: métodos contendo %2F, %5C ou %2E (em qualquer capitalização) continuavam passando a ACL como um segmento único, sem decodificação — mas o servidor HTTP do app de destino decodificava essas sequências por conta própria antes de rotear. O resultado prático é o mesmo bypass de abril, só que por uma via que o primeiro patch não fechou.
O patch de 9 de outubro resolve essa parte: métodos com %2F, %5C, %2E (qualquer caixa) ou barra invertida literal agora são rejeitados antes da verificação de ACL, em vez de decodificados depois dela. Isso completa oficialmente o CVE-2026-41491 — a mesma CVE de abril, fechada de fato só agora.
É breaking change. Se algum dos seus apps legitimamente usa nomes de método com essas sequências codificadas (double-encoding, barra invertida literal, %5C single-encoded), essas chamadas passam a ser recusadas. Vale grepar seus appId/rotas de service invocation antes de atualizar, não depois.
As outras três falhas do mesmo patch
Nenhuma delas tem CVE numerado ainda — mas o impacto de cada uma é concreto o suficiente pra entrar na mesma prioridade do bypass de ACL, dependendo do que você roda:
- Headers de identidade do chamador podiam ser forjados. Um app chamando outro via service invocation podia enviar seus próprios valores de
dapr-caller-app-id,dapr-caller-namespaceoudapr-callee-app-id, e esses valores chegavam ao app de destino junto dos valores reais. Se o app de destino lê o primeiro valor que aparece pra decidir autorização ou isolamento por tenant, ele pode estar confiando na identidade errada. O Dapr corrigiu removendo esses headers antes de repassar a chamada e fazendo o sidecar de destino definir os valores ele mesmo — mas a lacuna só fecha de verdade quando todos os sidecars do mesh estão atualizados. - O Scheduler aceitava reminders em actors internos de workflow de outro app. O Scheduler validava namespace e
app-id, mas não o tipo do actor — então um app com identidade Dapr válida no mesmo namespace conseguia agendar, listar ou apagar reminders dos actors reservadosdapr.internal.<namespace>.<appid>.*de outro app. Na prática, isso permite disparar activities de workflow de terceiros, injetar eventos de timer, forjar resultado de activity, ou apagar em massa os reminders internos de outro app — inclusive crashar o sidecar que hospeda aquele actor com um timer malformado. - Resultado de workflow forjável via o executor actor reservado. Só afeta quem tem a feature preview
WorkflowsClusteredDeploymenthabilitada (desligada por padrão). Com ela ativa, um app conseguia chamar o executor actor reservado de outro app através do próprio sidecar — mesmo com umaWorkflowAccessPolicydeny-all e assinatura de histórico habilitadas. Quem sabe o ID de uma instância de workflow de outro app podia inserir resultado de activity forjado ou fechar o workflow com saída escolhida pelo atacante.
O que fazer
Atualize pra 1.18.6 (ou 1.17.16, se ainda estiver na branch anterior) o quanto antes se você usa qualquer uma destas três coisas:
- Access control policies em service invocation. O bypass por
%2F/%5C/%2Eafeta diretamente quem bloqueia rotas específicas via policy — é a mesma classe de risco do CVE de abril, só que a parte que faltava. - Autorização baseada no header
dapr-caller-app-idlido pelo app. Se seu código confia nesse header sem também validar a identidade mTLS subjacente, trate como prioridade — e lembre que a correção completa exige mesh 100% atualizado, não só o app afetado. - Workflows do Dapr em geral, mesmo sem a feature preview: o bug do Scheduler com reminders cross-actor afeta qualquer app usando workflow em namespace compartilhado com outros apps, não só quem usa
WorkflowsClusteredDeployment.
Se você não usa controle de acesso por policy em service invocation, não lê headers de identidade do chamador na sua lógica de autorização, e não usa workflows do Dapr — o patch ainda vale aplicar, mas sem a urgência dos três cenários acima.
Um ponto que vale lembrar ao avaliar esse tipo de patch: “completar” uma CVE de seis meses atrás não é incomum em software que lida com normalização de path e encoding — é a mesma classe de bug que apareceu nas CVEs de path parameter do Envoy em agosto. Normalizar uma string pra decidir permissão, e normalizar de novo (ou de forma diferente) pra decidir roteamento, é terreno fértil pra esse tipo de divergência. Se seu próprio sistema faz validação de ACL baseada em string antes de outro componente fazer parsing daquela mesma string, vale perguntar se os dois usam exatamente a mesma normalização — porque “quase a mesma” é o suficiente pra abrir brecha.