Webhook signing
Verify that outgoing LoggerMan webhooks were sent by your project.
When you configure an outgoing webhook with a secret, LoggerMan sends:
X-LoggerMan-Secret— shared secret (legacy; prefer signature verification)X-LoggerMan-Signature—sha256=<hex>HMAC of the raw JSON body
Verification (Node.js)
HMAC verify
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyLoggerManWebhook(
rawBody: string,
secret: string,
signatureHeader: string | null
): boolean {
if (!signatureHeader?.startsWith("sha256=")) return false;
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
const received = signatureHeader.slice("sha256=".length);
try {
return timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(received, "hex")
);
} catch {
return false;
}
}
// Express example
// app.post("/hooks/loggerman", express.raw({ type: "application/json" }), (req, res) => {
// const raw = req.body.toString("utf8");
// if (!verifyLoggerManWebhook(raw, process.env.WEBHOOK_SECRET!, req.get("X-LoggerMan-Signature"))) {
// return res.status(401).send("Invalid signature");
// }
// const log = JSON.parse(raw);
// ...
// });Important
- Verify against the raw request body before JSON parsing.
- Use constant-time comparison (
timingSafeEqual) to prevent timing attacks. - Rotate secrets in Integration settings if a webhook endpoint is compromised.