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.