Webhooks
Aprende como configurar webhooks para tu aplicacion.
Como funcionan los Webhooks
Los Webhooks de cside son una forma facil de recibir notificaciones sobre eventos importantes en tu cuenta de cside. Los webhooks se pueden usar para activar acciones en tu aplicacion, enviar mensajes a tus canales de Discord o Slack, y mas.
Cuando creas un endpoint de webhook, enviaremos una solicitud POST a la URL que hayas especificado. La solicitud contendra un payload JSON con informacion sobre el evento que activo el webhook.
La estructura de datos
Siempre te enviaremos un payload JSON estructurado con los siguientes campos:
event"alert.created"
sent_atstring
dataAlertCreatedObject
domain_idstring
destination_idstring
Eventos
A continuacion se muestran los IDs de eventos y sus payloads que se enviaran con los webhooks.
IDs de eventos
| ID | Nombre | Objeto data |
|---|---|---|
| alert.created | Alerta creada | Objeto Alert |
Objetos de eventos
type"URL"|"HASH"|"IP"|"DOMAIN"|"HOSTNAME"
domainstring
targetstring
action"alert"
Secreto HMAC (tambien conocido como x-cside-signature)
Calculamos un HMAC al vuelo, usando un hash SHA256 del payload y tu secreto de webhook que te fue proporcionado cuando creaste el endpoint de webhook por primera vez. Esta firma se incluye en la cabecera x-cside-signature de la solicitud.
TE RECOMENDAMOS ENCARECIDAMENTE QUE USES ESTO PARA VERIFICAR QUE LA SOLICITUD PROVIENE DE cside: No hacerlo podria dejarte vulnerable a ataques de repeticion.
Verificar el secreto HMAC
Si estas usando JavaScript, te sugerimos usar nuestro paquete JavaScript para ayudarte a verificar la firma. Hemos proporcionado ejemplos en esa pagina que te ayudaran a comenzar.
Si no estas usando JavaScript, puedes verificar la firma calculando el hash HMAC SHA256 del cuerpo de la solicitud usando tu secreto de webhook, y comparandolo con la cabecera (x-cside-signature) que enviamos con cada solicitud.
Aqui hay algunos ejemplos en diferentes lenguajes:
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_sig