In this article
Simples nem sempre significa seguro: evite este padrão de XSS em Golang
Ataques de cross-site scripting (XSS) são uma vulnerabilidade comum da web que permite a invasores injetar scripts maliciosos em páginas visitadas por outros usuários. Você poderia pensar que manter as coisas simples resultaria em um código mais seguro. Sem dependências de terceiros, menos abstrações. Parece ideal, mas será que é?
Este artigo apresenta um servidor web simples escrito em Golang e mostra por que simplicidade nem sempre significa segurança.
Sobre ataques de cross-site scripting
Cross-site scripting (XSS) é uma técnica que usa scripts para roubar dados de usuários, sequestrar sessões ou desfigurar sites. Embora Golang ofereça ferramentas robustas para desenvolvimento web, a linguagem não está imune a vulnerabilidades de XSS quando as precauções necessárias não são tomadas.
Exemplo de cross-site scripting em Golang
Uma fonte frequente de vulnerabilidades de XSS é a inserção direta de dados fornecidos pelo usuário na saída HTML, sem a sanitização adequada ou outros controles de segurança. Vale lembrar que sanitizar nem sempre é o controle de segurança mais eficaz; muitas vezes, o ideal é codificar a saída.
Um exemplo de aplicação Go é aquela que recebe dados de um usuário por meio de um campo de formulário ou parâmetro de URL (como uma string de consulta) e os insere diretamente em uma página HTML como parte da resposta HTTP. Um invasor poderia injetar código JavaScript malicioso (daí o nome cross-site scripting). Quando outro usuário acessa a página, o navegador executa o script injetado, o que pode comprometer seus dados ou sua sessão.
Em servidores HTTP escritos em Golang, um erro comum é usar fmt.Fprint ou funções semelhantes para gravar dados fornecidos pelo usuário diretamente na resposta HTTP. Veja o trecho de código a seguir:
http.HandleFunc("/greet", func(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
response := fmt.Sprintf("<html><body><h1>Hello, %s!</h1></body></html>", name)
fmt.Fprint(w, response)
})Se um usuário definir a string de consulta name com uma entrada como <script>alert('XSS!')</script>, este código injetará o código JavaScript alert() na página, demonstrando um ataque básico de XSS. A função fmt.Sprintf não escapa automaticamente entidades HTML, deixando a aplicação vulnerável.
Esse trecho de código em Golang faz parte de um desafio de segurança de código aberto. A Snyk importou esse repositório de código e conseguiu detectar a presença de dados de entrada não sanitizados provenientes da URL da solicitação e entender como eles chegam à chamada insegura da função fmt.Fprint, que renderiza a string do template HTML. A análise completa do código-fonte e do caminho do código feita pelo SAST da Snyk mostra os resultados em mais detalhes:

Como corrigir XSS em Golang
O exemplo vulnerável em Golang acima mostra a importância de escapar ou sanitizar corretamente os dados fornecidos pelo usuário antes de incluí-los em respostas HTML.
Escapar código HTML potencialmente perigoso significa que o código da aplicação ou a dependência de terceiros utilizada precisa codificar determinados dados fornecidos pelo usuário, para que eles não sejam interpretados como elementos nativos do DOM HTML. Por exemplo, frameworks de frontend como React ou Vue convertem o caractere < em sua entidade HTML equivalente, que é <.
Isso significa que você deve sempre depender de dependências de terceiros? Não. Mas, se você monitorar e analisar ativamente essas dependências em busca de vulnerabilidades de segurança e mantê-las atualizadas com manutenção adequada e atualizações automatizadas, fica mais fácil controlar os riscos de segurança. Também é preciso considerar que o uso incorreto da biblioteca ainda pode introduzir uma vulnerabilidade.
E quanto a problemas de segurança no código em Golang? A Snyk oferece amplo suporte para Go, incluindo código Go, dependências Go e gerenciadores de pacotes.
Ferramenta gratuita online para verificar código
Proteja seu código antes do próximo commit.