In this article
O aprendizado de máquina pode encontrar vulnerabilidades de path traversal em Go? O Snyk Code pode!
Quem não gosta de um bom desafio de segurança? Eu gosto, mas você acha que um algoritmo de aprendizado de máquina consegue detectar vulnerabilidades de path traversal? Vamos colocar isso à prova!
Nas últimas semanas, Zeyad AbuLaban compartilhou uma série de publicações sobre código seguro e vulnerabilidades de segurança. Na série “Secure Code Quest”, ele apresenta vulnerabilidades de vários tipos e em diferentes linguagens.
Quando Zeyad publicou o Secure Code Quest #5, em vez de ir direto ao código da imagem para tentar identificar padrões inseguros, tive outra ideia: “Se eu colar esse código Go na minha IDE e fizer uma varredura com a extensão do Snyk para VS Code, será que ela vai detectá-lo?”

Este código Golang está vulnerável ou não?
Vamos começar organizando o código desse programa Go para inspecioná-lo com mais atenção, como em um processo adequado de revisão de código.
Este programa Golang lida com arquivos e, por isso, inclui uma função downloadHandler() que atua como um controlador HTTP. Ela espera receber um filename no parâmetro de consulta, limpar o caminho e sanitizar os dados por segurança. Em seguida, constrói o caminho para um arquivo em uma pasta de armazenamento no disco (baseDir := “public/files/”), concatenando o nome do arquivo a um diretório raiz.
package main
import (
// ... imports ...
)
func main() {
// ... main function code ...
}
func downloadHandler(w http.ResponseWriter, r *http.Request) {
filename := r.URL.Query().Get("filename")
if filename == "" {
http.Error(w, "Missing filename parameter", http.StatusBadRequest)
return
}
// Preventing Path Traversal
sanitizedFilename := strings.Replace(filename, "../", "", -1)
cleanedFilename := filepath.Clean(sanitizedFilename)
baseDir := "public/files/"
fullPath := filepath.Join(baseDir, cleanedFilename)
// ... code to handle file serving ...
}Como este programa Go implementa controles de segurança? Ele usa uma lógica de substituição de strings para trocar todas as ocorrências de ../ em um nome de arquivo por uma string vazia, removendo-as completamente do nome informado pelo usuário.
Vamos imaginar a seguinte requisição HTTP:
curl "http://localhost:8080/download?filename=../../app/flag.txtEssa requisição HTTP fará com que a variável filename seja sanitizada para remover todos os caminhos ../, deixando apenas filename como valor de entrada de app/flag.txt. Em seguida, esse valor será combinado com o caminho baseDir, resultando no caminho completo public/files/app/flag.txt.
Então, como você contornaria essa proteção?
Como você montaria a requisição HTTP para capturar a flag /app/flag.txt, no estilo de um Capture the Flag, e vencer o desafio para ganhar o prêmio?
Antes de revelar o payload, vou mostrar o que acontece quando você cola esse programa Golang na IDE.
Protegendo código com aprendizado de máquina
Primeiro, adicionei essa lógica como uma nova rota na minha aplicação web, que usa Gin. Por isso, a declaração da rota está um pouco diferente aqui. Depois, você pode ver como completei o código após a variável fullPath para verificar se o arquivo é válido e, por fim, enviá-lo de volta ao cliente.

Agora imagine que você tem a extensão da Snyk instalada na IDE.
Basta salvar o arquivo e, segundos depois (sim, só alguns segundos mesmo), você recebe uma auditoria de segurança do código que analisa seu código-fonte, incluindo dependências, Dockerfile, Terraform etc.
Além de apresentar um relatório de segurança, a extensão da Snyk para IDE também destaca a linha de código vulnerável, como um linter, chamando sua atenção para o problema. Ela ainda oferece outras ferramentas para você investigar a questão de segurança:
O nome e os detalhes da vulnerabilidade de segurança.
O fluxo de dados da origem ao destino mostra como dados não sanitizados chegam a APIs sensíveis.
Saiba mais sobre esta vulnerabilidade de path traversal se você está ouvindo falar dela pela primeira vez.
Exemplos de código corrigido que você pode aplicar se não souber como resolver a vulnerabilidade.
Em alguns casos, a Snyk também oferece o Snyk Agent Fix para resolver o problema de segurança automaticamente, refatorando o código para remover a vulnerabilidade sem alterar sua lógica.

O que o aprendizado de máquina tem a ver com isso? Tudo.
O SAST da Snyk (teste estático de segurança de aplicações) analisa seu código-fonte e, em seguida, o processa pelo mecanismo proprietário de aprendizado de máquina da Snyk. Esse mecanismo de segurança é baseado em um algoritmo robusto de IA simbólica, treinado com grandes bases de código e aprimorado para reconhecer padrões de código inseguro, classificados e rotulados por especialistas em segurança durante um processo de ajuste fino.
Esse processo técnico avançado é executado em segundos, direto na minha IDE, e oferece velocidade e precisão incomparáveis na detecção de vulnerabilidades de segurança no meu código. O mecanismo também foi treinado para reconhecer o que é considerado “bom” e analisou correções de segurança reais em repositórios de código aberto para sugerir diferenças de código com exemplos corrigidos, que posso aplicar se não tiver certeza de como implementar uma correção de segurança.
A combinação de algoritmos de aprendizado de máquina generativa e IA simbólica contribui para a experiência incrivelmente produtiva da Snyk na detecção de vulnerabilidades no código. Saiba mais sobre como a Snyk garante a adoção segura da IA.
Explorando path traversal em Golang
Ah, é mesmo. Voltando ao nosso desafio de segurança: como exploramos o path traversal no programa Golang apresentado e capturamos a flag?
Relembrando, esta é a lógica de prevenção de path traversal no programa Golang:
// Preventing Path Traversal
sanitizedFilename := strings.Replace(filename, "../", "", -1)
cleanedFilename := filepath.Clean(sanitizedFilename)A lógica de substituição de strings procura uma correspondência exata com o texto ../. Isso significa que, se o nome do arquivo contiver o padrão clássico de path traversal, como “../”, ele será substituído.
Mas o que acontece se modificarmos o texto de path traversal para contornar a lógica de correspondência exata? Veja o seguinte payload HTTP com o valor de entrada filename alterado:
curl "http://localhost:8080/download?filename=....//....//app/flag.txtQuando o valor da string de consulta filename passa a ser ....//....//app/flag.txt, as ocorrências de “../” são encontradas no nome do arquivo e removidas. Restam, então, os “..” e as barras “/” isoladas no nome do arquivo. Com isso, o valor de sanitizedFilename passa a ser ../../app/flag.txt, que sai do diretório base (public/files/) e envia o arquivo flag.txt ao cliente.
Participe do Fetch the Flag 2026!
Teste suas habilidades de segurança no nosso evento Capture the Flag, de 12 a 13 de fevereiro, das 12h às 12h (horário do leste dos EUA).