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.
The webhook REST APIs enable you to manage repository, organization, and app webhooks. You can also use the REST API to change the configuration of the 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:
- API REST para os webhooks dos repositórios
- Organization Webhooks REST API
- aplicativo GitHub Webhooks REST API
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:
- Navegue até o repositório onde você está configurando seu webhook.
- Preencha a caixa de texto do segredo. Use uma string aleatória com alta entropia (por exemplo, pegando a saída de
ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'
no terminal). - Clique em Atualizar o 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 pré-programe o token no seu aplicativo!
Validar cargas do GitHub
Quando seu token secreto está definido, GitHub Enterprise Server o utiliza para criar uma assinatura de hash com cada carga. Esta assinatura de hash está incluída com os 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 melhorar 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
O objetivo é calcular um hash usando seu SECRET_TOKEN
e garantir que o resultado corresponda ao hash de GitHub Enterprise Server. GitHub Enterprise Server 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 de 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:
-
Não importa qual implementação você usa, a assinatura de hash começa com
sha256=
, usando a chave de o token do seu segredo e o texto da sua carga. -
Não se recomenda usar um operador simples de
==
. Um método comosecure_compare
executa uma comparação de strings "tempo constante", o que ajuda a mitigar certos ataques de tempo contra operadores de igualdade regular.