Verificación y Seguridad
Verifica las firmas de webhooks de Whatalo usando HMAC-SHA256 para prevenir solicitudes forjadas y ataques de replay.
Cada solicitud de webhook de Whatalo incluye una firma HMAC-SHA256. Siempre verifica esta firma antes de procesar cualquier payload de evento — garantiza que la solicitud se originó en Whatalo y no ha sido manipulada.
Verificación con el SDK (Simple)
Para la mayoría de los plugins, el helper del SDK es el camino más rápido:
import { verifyWebhook } from "@whatalo/plugin-sdk/webhooks";
// rawBody must be the raw, unparsed request body string
const isValid = verifyWebhook({
payload: rawBody,
signature: req.headers["x-webhook-signature"] as string,
secret: process.env.WHATALO_CLIENT_SECRET!,
});
if (!isValid) {
return res.status(401).json({ error: "Invalid signature" });
}Esto realiza la verificación HMAC-SHA256 usando tu secreto de cliente como clave. Es el método de verificación base.
Verificación Mejorada con Protección Contra Replay (Recomendado)
La plantilla generada por whatalo init incluye un verificador más robusto (src/webhooks/verify.ts) que también protege contra ataques de replay:
// src/webhooks/verify.ts (scaffolded by whatalo init)
/**
* Verifies the HMAC-SHA256 signature of an incoming Whatalo webhook request.
* Includes replay protection: signatures older than 300 seconds are rejected.
*/
function verifyWhataloWebhook(
headers: Record<string, string | string[] | undefined>,
rawBody: string,
secret: string
): { valid: boolean; reason?: string }Esta versión mejorada:
- Firma
${timestamp}.${rawBody}— incluye el timestamp en el contenido firmado - Aplica una ventana de tolerancia de replay de 300 segundos — las solicitudes con más de 5 minutos se rechazan aunque la firma sea válida
- Lee tres encabezados:
X-Webhook-Id,X-Webhook-Timestamp,X-Webhook-Signature - Devuelve un resultado estructurado con un campo opcional
reasonpara depuración
Uso
import { verifyWhataloWebhook } from "@/webhooks/verify";
const result = verifyWhataloWebhook(
req.headers as Record<string, string | undefined>,
rawBody,
process.env.WHATALO_CLIENT_SECRET!
);
if (!result.valid) {
console.warn("Webhook verification failed:", result.reason);
return res.status(401).json({ error: "Invalid signature" });
}Encabezados Enviados con Cada Webhook
| Encabezado | Descripción |
|---|---|
X-Webhook-ID | Identificador único de entrega — úsalo para verificaciones de idempotencia |
X-Webhook-Event | Tipo de evento (e.g., order.created) |
X-Webhook-Signature | Firma HMAC-SHA256 |
X-Webhook-Timestamp | Marca de tiempo Unix de cuándo se generó la firma |
Algoritmo de Firma
Whatalo genera la firma de la siguiente manera:
- Concatenar:
${timestamp}.${rawBody} - Calcular HMAC-SHA256 usando tu secreto de cliente como clave
- Codificar el resultado en hexadecimal
- Enviar como
X-Webhook-Signature
Puedes replicar esto en cualquier lenguaje:
import crypto from "node:crypto";
function computeSignature(rawBody: string, timestamp: string, secret: string): string {
const signedContent = `${timestamp}.${rawBody}`;
return crypto
.createHmac("sha256", secret)
.update(signedContent)
.digest("hex");
}Lista de Verificación de Seguridad
Omitir cualquiera de estas verificaciones expone tu plugin a solicitudes forjadas o reproducidas.
- Usa el body sin procesar — Parsea el JSON solo después de la verificación. Cualquier modificación al body antes de calcular el HMAC causará que la verificación falle.
- Compara firmas en tiempo constante — Usa
crypto.timingSafeEqualo el helper del SDK. La igualdad de cadenas (===) es vulnerable a ataques de timing. - Aplica la ventana de replay — Rechaza solicitudes con un
X-Webhook-Timestampde más de 5 minutos. - Valida
X-Webhook-Event— Solo procesa tipos de eventos que tu plugin declaró en el manifiesto. - Guarda
X-Webhook-IDpara idempotencia — Las entregas de webhooks pueden reintentarse. Procesa cada ID de entrega solo una vez.
Prueba de Webhooks Localmente
Usa el CLI para disparar eventos de prueba contra tu servidor de desarrollo local:
# Trigger an order.created event against your dev store
whatalo webhook trigger ORDER_CREATED --store mi-tienda-devEl CLI firma la solicitud con tu secreto de cliente de desarrollo, por lo que tu lógica de verificación funciona exactamente igual que en producción. Solo funciona con tiendas de desarrollo.
Consulta la Referencia CLI — webhook para la lista completa de eventos de prueba soportados.