Webhooks
Configura destinos de webhook para recibir alertas de seguridad de c/side mediante solicitudes HTTP POST con verificación de firma HMAC.
Cómo funcionan los webhooks
Los webhooks te permiten recibir notificaciones de c/side como solicitudes HTTP POST a una URL que especifiques. Cuando se activa un disparador, c/side envía un payload JSON a tu endpoint de webhook con detalles sobre el evento.
Puedes configurar webhooks en tres formatos:
- JSON - payload JSON estándar para integraciones personalizadas
- Slack - preformateado para canales de Slack
- Discord - preformateado para canales de Discord
Agregar un destino de webhook
Para agregar un webhook como destino en una configuración de notificación:
- Abre el panel de control y navega a Team Settings > Notifications
- Crea una nueva configuración de notificación o edita una existente
- En Send To, haz clic en Add destination y selecciona Webhook
- En el panel de Configuration, completa:
- Endpoint URL: la URL donde quieres recibir las notificaciones de webhook (por ejemplo,
https://example.com/cside/notify) - Secret: una clave secreta usada para firmar las solicitudes de webhook (usada para la verificación HMAC)
- Format: elige JSON, Slack o Discord
- Endpoint URL: la URL donde quieres recibir las notificaciones de webhook (por ejemplo,
- Haz clic en Save o Save & Test
El payload del webhook
Cada solicitud de webhook contiene un payload JSON estructurado con los siguientes campos:
event"alert.created"
sent_atstring
dataAlertCreatedObject
domain_idstring
destination_idstring
Events
A continuación se muestran los IDs de eventos y sus payloads enviados con los webhooks.
Event IDs
| ID | Nombre | Objeto data |
|---|---|---|
| alert.created | Alert Created | Alert Object |
Objetos de evento
type"URL"|"HASH"|"IP"|"DOMAIN"|"HOSTNAME"
domainstring
targetstring
action"alert"
Verificación HMAC
Cada solicitud de webhook incluye un encabezado x-cside-signature que contiene un hash HMAC SHA256 del cuerpo de la solicitud, firmado con el secret que proporcionaste al crear el destino de webhook.
Siempre debes verificar esta firma para confirmar que la solicitud proviene de c/side y prevenir ataques de repetición.
Cómo verificar la firma
Si estás usando JavaScript, usa nuestro paquete JavaScript para verificación integrada.
Para otros lenguajes, calcula el hash HMAC SHA256 del cuerpo crudo de la solicitud usando tu secret de webhook, y luego compáralo con el valor del encabezado x-cside-signature.
async function verifyHmac(body: string, signature: string, secret: string) {
const encoder = new TextEncoder();
const encodedBody = encoder.encode(body);
const key = await crypto.subtle.importKey(
"raw",
encoder.encode(secret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"]
);
const signatureBuffer = await crypto.subtle.sign("HMAC", key, encodedBody);
const finalSig = Array.from(new Uint8Array(signatureBuffer))
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("");
return signature.toLowerCase() === finalSig;
}fn verify_hmac(body: &str, signature: &str, secret: &str) -> Result<(), &'static str> {
let mut mac = HmacSha256::new_from_slice(secret.as_bytes()).map_err(|_| "Invalid secret")?;
mac.update(body.as_bytes());
let result = mac.finalize();
let code_bytes = result.into_bytes();
let final_sig = hex::encode(code_bytes);
if signature.to_lowercase() == final_sig {
Ok(())
} else {
Err("Invalid signature")
}
}
// Add to Cargo.toml:
// [dependencies]
// hmac = "0.12"
// sha2 = "0.10"
// hex = "0.4"package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"strings"
)
func verifyHmac(body, signature, secret string) bool {
h := hmac.New(sha256.New, []byte(secret))
h.Write([]byte(body))
finalSig := hex.EncodeToString(h.Sum(nil))
return strings.ToLower(signature) == finalSig
}defmodule HmacVerifier do
def verify_hmac(body, signature, secret) do
final_sig =
:crypto.mac(:hmac, :sha256, secret, body)
|> Base.encode16(case: :lower)
String.downcase(signature) == final_sig
end
endimport hmac
import hashlib
import secrets
def verify_hmac(body: str, signature: str, secret: str) -> bool:
final_sig = hmac.new(
secret.encode('utf-8'),
body.encode('utf-8'),
hashlib.sha256
).hexdigest()
return signature.lower() == final_sigThanks for your feedback!