Asegurar tus webhooks

Asegúrate de que tu servidor está recibiendo únicamente las solicitudes de GitHub esperadas por razones de seguridad.

Una vez que tu servidor se configure para recibir cargas útiles, éste escuchará a cualquiera de ellas que se envíe a la terminal que configuraste. Por razones de seguridad, probablemente quieras limitar las solicitudes a aquellas que vengan de GitHub. Hay algunas formas de solucionar esto, por ejemplo, podrías decidir el permitir las solicitudes que vengan de la dirección IP de GitHub, pero una manera mucho más fácil es configurar un token secreto y validar la información.

Las API de REST de los webhooks te permiten administrar webhooks de repositorio, organización y aplicación. Puedes utilizar esta API para listar las entregas de webhook para uno de ellos u obtener y volver a hacer una entrega individual para uno de ellos, la cual puede integrarse en una app o servicio externo.. También puedes utilizar la API de REST para cambiar la configuración del webhook. Por ejemplo, puedes modificar la URL de la carga útil, el tipo de contenido, la verificación de SSL, y el secreto. Para obtener más información, consulta:

Configurar tu token secreto

Necesitarás configurar tu token secreto en dos lugares: GitHub y tu servidor.

Para configurar tu token en GitHub:

  1. Navega al repositorio en donde configuraste tu webhook.
  2. Llena la caja de texto del secreto. Utiliza una secuencia aleatoria con entropía alta (por ejemplo, tomando la salida de ruby -rsecurerandom -e 'puts SecureRandom.hex(20)' en la terminal). Campo de webhook y de token secreto
  3. Da clic en Actualizar Webhook.

Después, configura una variable de ambiente en tu servidor, la cual almacene este token. Por lo general, esto es tan simple como el ejecutar:

$ export SECRET_TOKEN=your_token

¡Jamás preprogrames el token en tu app!

Validar cargas útiles de GitHub

Cuando se configura tu token secreto, GitHub lo utiliza para crear una firma de hash con cada carga útil. This hash signature is included with the headers of each request as X-Hub-Signature-256.

Nota: Para tener compatibilidad en versiones anteriores, también incluimos el encabezado X-Hub-Signature que se genera utilizando la función de hash SHA-1. De ser posible, te recomendamos que utilices el encabezado de X-Hub-Signature-256 para mejorar la seguridad. El ejemplo siguiente demuestra cómo utilizar el encabezado X-Hub-Signature-256.

Por ejemplo, si tienes un servidor básico que escucha a los webhooks, puede configurarse de forma similar a esto:

require 'sinatra'
require 'json'

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

La intención es calcular un hash utilizando tu SECRET_TOKEN, y asegurarse de que el resultado empate con el hash de GitHub. GitHub utiliza un resumen hexadecimal de HMAC para calcular el hash, así que podrías reconfigurar tu servidor para que se viera así:

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

Nota: Las cargas útiles de los webhooks pueden contener caracteres en unicode. Si tu implementación de idioma y servidor especifican un cifrado de caracteres, asegúrate de que estés manejando la carga útil como UTF-8.

Tus implementaciones de lenguaje y de servidor pueden diferir de esta muestra de código. Sin embargo, hay varias cosas muy importantes que destacar:

  • No matter which implementation you use, the hash signature starts with sha256=, using the key of your secret token and your payload body.

  • No se recomienda utilizar un simple operador de ==. Un método como el de secure_compare lleva a cabo una secuencia de comparación de "tiempo constante" que ayuda a mitigar algunos ataques de temporalidad en contra de las operaciones de igualdad habituales.

¿Te ayudó este documento?

Política de privacidad

¡Ayúdanos a hacer geniales estos documentos!

Todos los documentos de GitHub son de código abierto. ¿Notas algo que esté mal o que no sea claro? Emite una solicitud de cambios.

Haz una contribución

O, aprende cómo contribuir.