Skip to main content

Protegendo seus webhooks

Certifique-se de que seu servidor só esteja recebendo as solicitações esperadas do GitHub por motivos de segurança.

Assim que seu servidor estiver configurado para receber cargas, ele ouvirá qualquer carga enviada para o ponto de extremidade que você configurou. Por motivos de segurança, você provavelmente vai querer limitar os pedidos para aqueles provenientes do GitHub. Existem algumas maneiras de fazer isso. Você poderia, por exemplo, optar por permitir solicitações do endereço IP do GitHub. No entanto, um método muito mais fácil é configurar um token secreto e validar a informação.

As APIs REST do webhook permitem que você gerencie webhooks do repositório, da organização e do aplicativo. Você pode usar essa API para listar as entregas de webhook para um webhook ou obter e entregar novamente uma entrega individual para um webhook, que pode ser integrado a um aplicativo ou um serviço externo. Use também a API REST para alterar a configuração do webhook. Por exemplo, você pode modificar a URL da carga, tipo de conteúdo, verificação de SSL e segredo. Para obter mais informações, consulte:

Definir seu token secreto

Você precisará configurar seu token secreto em dois lugares: no GitHub e no seu servidor.

Para definir seu token no GitHub:

  1. Navegue até o repositório em que você está configurando seu webhook.
  2. Preencha a caixa de texto do segredo. Use uma cadeia de caracteres aleatória com alta entropia (por exemplo, usando a saída de ruby -rsecurerandom -e 'puts SecureRandom.hex(20)' no terminal). Campo de token secreto do webhook
  3. Clique em Atualizar Webhook.

Em seguida, configure uma variável de ambiente em seu servidor que armazene este token. Normalmente, isso é tão simples quanto executar:

$ export SECRET_TOKEN=your_token

Nunca embuta o token em código no aplicativo.

Validando conteúdos do GitHub

Quando seu token secreto está definido, GitHub Enterprise Cloud o utiliza para criar uma assinatura de hash com cada carga. Essa assinatura de hash é incluída nos cabeçalhos de cada solicitação como x-hub-signature-256.

Observação: para compatibilidade com versões anteriores, também incluímos o cabeçalho x-hub-signature gerado usando a função de hash SHA-1. Se possível, recomendamos que você use o cabeçalho x-hub-signature-256 para aprimorar a segurança. O exemplo abaixo demonstra o uso do cabeçalho x-hub-signature-256.

Por exemplo, se você tem um servidor básico que ouve webhooks, ele poderá ser configurado de forma semelhante a isso:

require 'sinatra'
require 'json'

post '/payload' do
  request.body.rewind
  push = JSON.parse(request.body.read)
  "I got some JSON: #{push.inspect}"
end

A intenção é calcular um hash usando o SECRET_TOKEN e garantir que o resultado corresponda ao hash do GitHub Enterprise Cloud. GitHub Enterprise Cloud usa um resumo hexadecimal HMAC para calcular o hash. Portanto, você pode reconfigurar o seu servidor para que se pareça mais ou menos assim:

post '/payload' do
  request.body.rewind
  payload_body = request.body.read
  verify_signature(payload_body)
  push = JSON.parse(payload_body)
  "I got some JSON: #{push.inspect}"
end

def verify_signature(payload_body)
  signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), ENV['SECRET_TOKEN'], payload_body)
  return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE_256'])
end

Observação: as cargas de webhook podem conter caracteres Unicode. Se o seu idioma e a implementação de servidor especificarem uma codificação de caracteres, certifique-se de que você manipula a carga como UTF-8.

A sua linguagem e implementações do servidor podem ser diferentes deste código de exemplo. No entanto, há uma série de aspectos muito importantes a destacar:

  • Independentemente da implementação usada, a assinatura de hash começa com sha256=, usando a chave do token secreto e o corpo da carga.

  • Não ==recomendamos usar um operador simples. Um método como secure_compare executa uma comparação de cadeia de caracteres de "tempo constante", que ajuda a atenuar determinados ataques de tempo contra operadores de igualdade regulares.