Uma pull request deveria trazer código para revisão. Em certos workflows, porém, até o nome da branch pode virar entrada para um shell — e, com isso, abrir caminho para executar comandos no runner.
Uma advisory publicada no GitHub descreve uma falha crítica no wktk/conflibot, Action usada para detectar conflitos entre PRs. Nas versões anteriores à 1.2.1, a Action montava comandos Git por interpolação de texto e os executava pelo shell. A branch de uma PR vinda de fork é controlada por quem abre a contribuição; se ela traz caracteres especiais, deixa de ser só um nome.
O caso é específico dessa Action, mas a lição serve para qualquer equipe: dados de uma pull request não são confiáveis só porque chegaram pelo GitHub. Título, descrição, branch, nome de arquivo e conteúdo do diff podem ser controlados por alguém de fora do repositório.
Por que pull_request_target muda o tamanho do risco
O cenário fica perigoso quando o job roda no evento pull_request_target. Ele usa o contexto do repositório-base e pode ter acesso a segredos e a um GITHUB_TOKEN com permissões de escrita. É útil para algumas automações, mas exige separar com rigor o que recebe dados da PR do que pode tocar em credenciais.
Segundo a advisory, uma branch criada com metacaracteres de shell podia provocar execução arbitrária no runner quando a Action processava a referência. Não era preciso permissão especial nem interação de maintainer: bastava abrir a PR para o workflow configurado rodar.
O que checar hoje
- Procure por Conflibot. Busque
wktk/conflibotem.github/workflows, inclusive em repositórios menos ativos. - Atualize a versão. A correção está em 1.2.1 e 2.0.0; a recomendação atual é usar
wktk/conflibot@v2. Em runners hospedados pelo GitHub, a troca é direta; runners próprios precisam ter Node.js 24 e Git 2.38 ou superior. - Leia cada uso de
pull_request_target. Não basta trocar uma Action. Veja se algum passo usa valores de branch, título, corpo ou arquivos da PR para montar comandos, URLs ou configurações. - Reduza permissões por job. Declare
permissionsno menor escopo possível e evite disponibilizar segredos a workflows que processam contribuições externas. - Não faça checkout do código da PR nesse contexto sem necessidade real. Misturar código ou dados de um fork com token de escrita é uma combinação que merece revisão explícita.
O erro não é só usar shell
Chamar Git pelo shell com valores externos é o ponto técnico da falha, mas o problema maior é tratar uma entrada de PR como se fosse metadado inocente. A correção do Conflibot foi trocar comandos montados em texto por arrays de argumentos com execFile/spawn e passar a usar a PR por número, em refs/pull/<número>/head.
Essa é uma boa régua para automações internas: quando um valor externo precisa virar argumento, passe-o como argumento; não o cole dentro de uma string que será interpretada. E, quando a automação realmente precisar de credenciais, isole-a de qualquer evento que aceite contribuição de terceiros.
Não é um chamado para abandonar Actions de PR. É um lembrete para olhar o workflow como código de produção: ele tem entradas, privilégios e uma superfície de ataque própria. Se o seu CI usa pull_request_target, esta é uma revisão que vale entrar na próxima janela — antes que uma branch seja mais do que uma branch.