Cómo validar integridad de webhooks con HMAC
Clase 24 de 30 • Curso de Ciberseguridad para Desarrollo Web
Contenido del curso
Funciona en mi local
Introducción a DevSecOps
Seguridad en la arquitectura
- 11

Arquitectura AWS para métricas de Git
02:24 min - 12

Configuración de AWS CLI para Terraform
09:34 min - 13

Terraform IAM: roles y policies automáticos
17:44 min - 14

Modificando main.tf para enlazar módulos IAM en Terraform
06:02 min - 15

Bucket S3 para Lambdas con Terraform
16:44 min - 16

Configuración de Postgres RDS con VPC y seguridad
14:10 min - 17

Configurando VPC para AWS Lambda con Terraform
12:29 min - 18

Cómo configurar API Gateway para Lambdas
05:42 min
Evitando vulnerabilidades en el código
- 19

Configuración completa de Auth0 para tokens
07:14 min - 20

Authorizer Lambda con Auth0 y JWT
16:56 min - 21

Conecta Go a Postgres usando AWS Secrets
13:35 min - 22

Conexión segura de Lambdas a Secrets con VPC
11:27 min - 23

Validación de webhooks desde GitHub con user-agent
12:08 min - 24

Cómo validar integridad de webhooks con HMAC
Viendo ahora
Controles de seguridad sobre datos
Monitoring y alertas
CORS y cierre
La validación de la integridad de los datos en webhooks de GitHub se resuelve con una firma HMAC SHA-256, un secret compartido y AWS Secrets Manager. Aquí verás cómo configurar el secret, dar permisos con Terraform, usar una variable de entorno en Lambda y validar la firma de forma segura en Go, sin exponer credenciales y con despliegue reproducible.
¿Cómo validar la integridad con el header firmado de GitHub?
GitHub envía un header con el body encriptado mediante una firma basada en el secret del webhook. Si calculas la firma localmente con el mismo secret y coincide con la del header, confirmas la integridad del payload.
- Crea un secret robusto con caracteres especiales y números. Copia el valor y actualiza el webhook con Update webhook.
- Acepta el aviso: no podrás volver a ver el secret; solo cambiarlo. Si lo cambias en GitHub, cambia también el que usas en AWS.
- La validación usa el algoritmo SHA-256 y un signature prefix tipo "sha256="; lo que sigue al igual es el valor a comparar.
¿Qué secret y permisos necesitas en AWS Secrets Manager?
El secret se guarda como mapa clave-valor en AWS Secrets Manager y se accede con una política mínima de lectura desde el rol de ejecución.
- Añade un nuevo secret en Secrets Manager como API key. Clave: "secret". Valor: el secret configurado en GitHub.
- Asigna un nombre claro, por ejemplo "GitHub secret". La clave de encriptación es la gestionada por Secrets Manager.
- La rotación de secrets es opcional; es una buena práctica para aplicaciones grandes, pero no se activó en este caso.
- Identifica datos clave: encryption key, secret name y secret ARN.
- Crea en Terraform una política IAM que permita obtener el secret. Nómbrala con intención, por ejemplo
can get GitHub webhook secret. - En la política, define el resource con el secret ARN exacto.
- Exporta el ARN vía
outputy pásalo como variable al módulo que ata la política al rol. - Ata la política al rol del servicio (por ejemplo, Repo Collector) usando la variable
can get GitHub secret Arn. - En la Lambda
handleGitHubWebhook, agrega la variable de entornoGITHUB_SECRETcon el nombre del secret, no el ARN.
¿Cómo validar la firma HMAC SHA-256 en Lambda con Go?
La lógica en Go calcula la firma del payload con el secret y la compara, de forma segura, contra el header de GitHub.
¿Qué funciones de ayuda implementas en Go?
CalculateSignature: recibe el secret y el payload; usa la librería nativa de Go para HMAC con SHA-256 y devuelve la firma.ValidateGitHubRequest: recibe el contexto y la request; retorna un booleano y un error. Pasos clave:- Leer el header de GitHub para la firma 256. Si no viene, se deniega.
- Definir
signaturePrefix = "sha256="y retirar el prefijo del valor del header. - Obtener el secret desde Secrets Manager con el cliente; parsear a JSON como mapa y tomar la clave "secret".
- Calcular la firma del body con
CalculateSignature. - Comparar de forma segura con
hmac.Equaly operar con bytes, no strings. - En el handler, si hay error, retornarlo; si no es válido, crear
errors.New("Invalid GitHub Webhook"). Evita redeclaraciones de variables retirando:=cuando ya exista.
Código orientativo en Go:
const signaturePrefix = "sha256="
func CalculateSignature(secret, payload []byte) []byte {
// usar HMAC con SHA-256 y devolver la firma.
return nil
}
func ValidateGitHubRequest(ctx context.Context, req Request) (bool, error) {
// 1) leer header de la firma 256.
// 2) quitar signaturePrefix.
// 3) traer secret desde Secrets Manager.
// 4) calcular firma y comparar con hmac.Equal usando bytes.
return true, nil
}
¿Cómo compilar, desplegar y verificar el flujo?
- En
handleGitHubWebhook, ejecuta make publish para compilar y subir a S3; Terraform no compila el código. - En infraestructura, corre terraform plan: verás 2 ítems para añadir (política y attach) y 3 recursos para cambiar (tus Lambdas).
- Aplica con terraform apply y confirma con "yes". Espera la finalización del despliegue.
- Realiza un git commit con mensaje "add data integrity validation" y haz push.
- En GitHub, revisa Recent deliveries: marcador verde y respuesta "ok".
- En tu base de datos, ejecuta select all from commits: verás el nuevo commit "Add data integrity validation" insertado correctamente.
¿Te gustaría profundizar en más controles de seguridad o ampliar métricas con datos de GitHub? Comparte tus dudas y cuéntame qué extenderías a continuación.