Documentazione

Monitoraggio e avvisi sulle modifiche

AppSafe confronta ogni scansione di un sito verificato con la precedente e ti dice cosa è cambiato. Con le scansioni programmate o la ri-scansione al deploy, questo diventa un monitoraggio continuo con avvisi via email, Slack, Discord o un webhook firmato.

Gli avvisi sulle modifiche sono inclusi nei piani Pro, Agency e Team. Le scansioni programmate sono giornaliere o settimanali su Pro e Agency, e ogni ora su Team.

Cosa confronta AppSafe

Gli avvisi vengono inviati per le scansioni programmate e per quelle al deploy, una sola volta per problema: un problema che resta invariato non genera un nuovo avviso alla scansione successiva. Se scompare e poi ricompare, riceverai di nuovo un avviso.

Configura gli avvisi

Apri un sito verificato nella tua dashboard e aggiungi i canali in Monitoraggio e avvisi. Ogni canale ha una gravità minima e un pulsante Invia avviso di prova.

Payload del webhook

I webhook generici ricevono questo JSON (Content-Type: application/json). Gli avvisi di prova usano l’evento monitoring.test e hanno scan impostato a null.

{
  "event": "monitoring.changes",
  "deliveryId": "5f2c9a0e41b7d3a8c6e1f0b2",
  "createdAt": "2026-10-26T12:00:00.000Z",
  "site": {
    "domain": "myapp.com"
  },
  "scan": {
    "id": "3f1c2b9e-1111-4222-8333-944455556666",
    "grade": "C",
    "score": 67,
    "reportUrl": "https://appsafe.dev/report/…"
  },
  "summary": "2 changes on myapp.com",
  "changes": [
    {
      "type": "header_removed",
      "severity": "high",
      "subject": "content-security-policy",
      "message": "content-security-policy header removed"
    },
    {
      "type": "finding_new",
      "severity": "critical",
      "subject": "baas-supabase-table-readable",
      "title": "Supabase tables readable without logging in",
      "message": "New issue: Supabase tables readable without logging in"
    }
  ]
}

Tipi di modifica: finding_new, finding_resolved, header_added, header_removed, header_weakened, header_changed, tls_changed, tls_expiring (con days), script_domain_new, sri_missing, subdomain_new, subdomain_dangling, dns_changed. Gravità: low, medium, high, critical. Gli avvisi includono solo le regressioni, quindi finding_resolved e header_added compaiono nella dashboard e nel report ma da soli non generano avvisi.

Verifica la firma

Ogni richiesta webhook ha un header X-AppSafe-Signature. Calcola un HMAC-SHA256 con il secret del canale su timestamp, un punto e il body grezzo della richiesta, e confrontalo con v1 in tempo costante. Rifiuta le richieste il cui timestamp è più vecchio di 5 minuti.

X-AppSafe-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">
X-AppSafe-Event: monitoring.changes | monitoring.test
import { createHmac, timingSafeEqual } from "node:crypto";

// header: the X-AppSafe-Signature value, e.g. "t=1761480000,v1=5d41…"
// body:   the raw request body (string), before JSON.parse
export function verifyAppSafeSignature(secret, header, body) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const timestamp = Number(parts.t);
  if (!parts.v1 || Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
  const expected = createHmac("sha256", secret).update(`${timestamp}.${body}`).digest();
  const given = Buffer.from(parts.v1, "hex");
  return given.length === expected.length && timingSafeEqual(given, expected);
}

AppSafe invia ogni avviso una sola volta e non riprova. Rispondi con uno stato 2xx entro 8 secondi. La dashboard mostra l’ultimo errore di consegna del canale.

Cosa non contengono mai gli avvisi

I payload degli avvisi contengono tipi di modifica, gravità, titoli dei problemi, nomi degli header, hostname di script e sottodomini e un link al report. Non contengono mai i dettagli dei problemi, secret (nemmeno oscurati) o dati personali.