Validación de webhooks desde GitHub con user-agent

Clase 23 de 30Curso de Ciberseguridad para Desarrollo Web

Resumen

La seguridad empieza por tus entradas: validar webhooks y evitar XSS (cross-site scripting) protege cookies, sesiones y datos. Aquí verás cómo enlazar API Gateway con un Lambda Authorizer, identificar el user-agent de GitHub y almacenar commits en base de datos, sin añadir nada externo.

¿Qué es XSS y por qué validar webhooks de GitHub?

La inyección de código tipo XSS explota entradas sin sanitizar para ejecutar JavaScript malicioso. Puede robar cookies, tomar cuentas o ejecutar acciones no deseadas. Aunque se ejemplifica en JavaScript, la idea aplica a cualquier lenguaje: validar entradas y su origen es clave.

En el flujo mostrado, se refuerza la confianza del origen validando el header user-agent. Cuando el webhook proviene de GitHub, el user-agent incluye un prefijo identificable. Así se filtran peticiones ajenas y se reduce el riesgo de que una entrada no confiable termine ejecutando lógica sensible.

  • XSS: inyección de scripts a través de entradas.
  • Validación de origen: usar headers como user-agent.
  • Webhooks: automatizan eventos de commit y despliegue.

¿Cómo configurar el webhook y el API Gateway hacia el endpoint real?

Primero se remplaza el endpoint temporal de ngrok por el endpoint real de API Gateway. Se copia desde Postman el endpoint de safe commit y se pega en Settings del webhook de GitHub. Luego, un commit fuerza la entrega y permite revisar recent deliveries para confirmar el 200.

Pasos prácticos:

  • Abrir Settings del webhook en GitHub.
  • Cambiar ngrok por el endpoint real de API Gateway.
  • Hacer commit y push para disparar el webhook.
  • Verificar 200 en recent deliveries.

Palabras clave:

  • Endpoint real. API Gateway. Postman. ngrok. recent deliveries. 200.

¿Cómo implementar el Lambda Authorizer y procesar handleGitHubWebhook?

Se crea y se adjunta un Lambda Authorizer al método POST del recurso de commit. En la configuración, se usa el header user-agent como fuente de identidad. En CloudWatch logs se observa que peticiones de GitHub llegan con un identitySource característico (por ejemplo, github-hookshot). La lógica compara el user-agent con un prefijo definido.

  • Authorizer: asociado al POST de commit.
  • identitySource: header user-agent en minúsculas.
  • Observabilidad: revisar CloudWatch logs para confirmar el origen.

¿Cómo validar el header user-agent con un prefix?

Se inicializa una constante de prefijo y se compara contra el user-agent. Si coincide, se permite el acceso; si no, se trata como otra petición y se restringe.

// Authorizer (Go): validación de user-agent con prefijo package main import ( "strings" ) const GITHUB_USERAGENT_prefix = "GITHUB-HOOKSHOT" func isFromGitHub(headers map[string]string) bool { ua := headers["user-agent"] if ua == "" { // sin user-agent: tratar como no-GitHub según tu política. return false } // comparación por prefijo (insensible a mayúsculas) return strings.HasPrefix(strings.ToUpper(ua), GITHUB_USERAGENT_prefix) }

Claves:

  • GITHUB_USERAGENT_prefix con valor "GITHUB-HOOKSHOT".
  • Comparación por prefijo en el Authorizer.

¿Cómo procesar y almacenar el webhook en handleGitHubWebhook?

El Lambda de handleGitHubWebhook toma el payload en JSON, hace marshal a la estructura interna, imprime el head commit y persiste con insertGitHubWebhook. Se reutilizan variables de entorno de la Lambda getMetrics para conectarse a la base de datos.

// Handler (Go): parseo y persistencia func handleGitHubWebhook(event []byte) error { // 1) Parsear JSON del webhook. // 2) Loggear el head commit para trazabilidad. // 3) Conectar a la base de datos (env vars ya configuradas). // 4) Llamar insertGitHubWebhook(time.Now(), payload). // 5) Retornar confirmación. return nil }

Operaciones clave:

  • insertGitHubWebhook: persistencia del webhook.
  • time.now: sello de tiempo para el commit.
  • Variables de entorno: reutilizadas desde getMetrics.

¿Cómo compilar, desplegar y verificar el flujo end-to-end?

Se compilan las Lambdas y se despliega la infraestructura. Luego se realiza un commit y se confirma el registro en base de datos consultando la tabla de commits.

  • Compilar: make publish en cada Lambda (authorizer y handleGitHubWebhook).
  • Planificar: terraform plan para ver 3 cambios en las Lambdas.
  • Aplicar: terraform apply y confirmar.
  • Disparar: commit y push en el repositorio.
  • Verificar: 200 en recent deliveries y SELECT en base de datos.

Comprobación en base de datos:

  • Consultar con: SELECT all from commits en tu gestor (por ejemplo, pgAdmin).
  • Verás commit ID largo, mensaje, author username, author email y payload en JSON.

Buenas prácticas destacadas:

  • Validar origen con user-agent antes de ejecutar lógica.
  • Registrar eventos (head commit) para trazabilidad.
  • Persistir payloads como referencia de auditoría.

¿Quieres compartir cómo validas la integridad de tus webhooks o qué políticas aplicas en tu Authorizer? Deja tus comentarios y experiencias.

      Validación de webhooks desde GitHub con user-agent