Sicherheit

Mit HTTPS und der persönlichen Webhook-Signatur kann dein System prüfen, ob eine Nachricht sicher übertragen wurde und wirklich von i-Planner stammt. Die kurze Checkliste richtet sich an alle; darunter folgen Codebeispiele für Entwickler.

Zuletzt geprüft: 10. September 2026

Das Wichtigste

Für einen sicheren Webhook sind vier Punkte entscheidend:

  1. Verwende ausschließlich eine öffentliche https://-Adresse.
  2. Teile das persönliche whsec_-Secret nur mit dem empfangenden System.
  3. Lass jede eingehende Nachricht anhand der Signatur prüfen.
  4. Wechsle das Secret, wenn es versehentlich offengelegt wurde oder ein Empfänger nicht mehr verwendet wird.

i-Planner ergänzt jeden HTTP-Aufruf um die benötigten Signatur-Header. Die technische Prüfung ist weiter unten mit Beispielen für Node.js, Python und PHP beschrieben.

Sichere Verbindung

HTTPS-Pflicht
Die Ziel-URL muss mit https:// beginnen. HTTP-URLs werden bereits beim Speichern abgelehnt — Plain-HTTP ist nicht möglich.
TLS-Validierung
i-Planner prüft das TLS-Zertifikat der Gegenstelle. Selbstsignierte oder abgelaufene Zertifikate führen zu einem FETCH_ERROR und damit zu einer Wiederholung (siehe Automatische Wiederholungen).

Sichere Ziel-Adresse

i-Planner prüft die Ziel-Adresse beim Speichern und erneut unmittelbar vor jeder Zustellung. Zeigt die Adresse auf ein internes Netzwerk oder eine nicht erlaubte Adresse, wird der Versand zum Schutz deiner Daten abgebrochen und nicht wiederholt. Im Audit-Log steht dann BLOCKED_PRIVATE_URL.

Abgelehnt wird:

Private IP-Bereiche
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 100.64.0.0/10 (CGNAT) — alles, was technisch nur in internen Netzen erreichbar wäre.
Loopback
127.0.0.0/8, ::1, localhost — diese Adressen sind aus i-Planner heraus ohnehin nicht erreichbar.
Link-local und Site-local
169.254.0.0/16, fe80::/10, fc00::/7.
Metadaten-Endpoints
AWS/GCP/Azure Metadata-IPs (169.254.169.254, …).
Nicht-Standard-Ports
Nur Port 443 (HTTPS-Standard) sowie übliche HTTPS-Proxy-Ports werden akzeptiert.

Wenn du in der Entwicklung gegen localhost testen willst, nutze einen Tunnel wie ngrok oder Cloudflare Tunnel — Details unter Lokal testen.

Signatur prüfen – für Entwickler

Jeder i-Planner-Webhook wird nach der Standard-Webhooks-Spezifikation signiert. Das persönliche Secret beginnt mit whsec_ und ist in den Webhook-Einstellungen unter HTTP-Signatur sichtbar.

Die Version des Nachrichtenformats steht separat im Header webhook-version (aktuell v1). Zur Signatur enthält der HTTP-Aufruf außerdem drei Standard-Webhooks-Header:

webhook-id
Eindeutige ID der Zustellung. Sie bleibt bei Wiederholungen gleich und ist der Schlüssel für deine Idempotenz-Prüfung.
webhook-timestamp
Unix-Sekunden des aktuellen Zustellversuchs. Lehne Werte außerhalb eines engen Fensters ab; empfohlen sind ± 5 Minuten.
webhook-signature
Eine oder während einer Rotation zwei space-separierte Signaturen im Format v1,<base64>.

Die signierte Nachricht ist exakt webhook-id + "." + webhook-timestamp + "." + rawBody. Verifiziere deshalb den unveränderten Roh-Body vor dem JSON-Parsing. Der HMAC-Key sind die base64-dekodierten Bytes hinter whsec_.

js
import { createHmac, timingSafeEqual } from 'node:crypto'

export function verifyIPlannerWebhook({ secret, headers, rawBody }) {
  const id = headers['webhook-id']
  const timestamp = headers['webhook-timestamp']
  const timestampNumber = Number(timestamp)
  if (!id || !Number.isSafeInteger(timestampNumber)
      || Math.abs(Date.now() / 1000 - timestampNumber) > 300) return false

  const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64')
  const expected = `v1,${createHmac('sha256', key)
    .update(`${id}.${timestamp}.`)
    .update(rawBody)
    .digest('base64')}`

  return String(headers['webhook-signature'] || '').split(' ').some(candidate => {
    const a = Buffer.from(candidate)
    const b = Buffer.from(expected)
    return a.length === b.length && timingSafeEqual(a, b)
  })
}

Secret sicher wechseln

Beim Wechsel bleibt das vorherige Secret noch 24 Stunden gültig. So kannst du das neue Secret zuerst im empfangenden System hinterlegen, ohne Zustellungen zu unterbrechen. Während dieser Übergangszeit enthält webhook-signature zwei v1-Werte; der Empfänger akzeptiert den Aufruf, sobald eine Signatur passt. Entferne das alte Secret nach Ablauf des angezeigten Zeitfensters.

Eigene HTTP-Header

Zusätzlich zur Signatur kannst du eigene Header wie Authorization oder X-API-Key hinterlegen. Sie werden bei jeder Zustellung mitgesendet. Verwende sie nur als zusätzliche Zugriffskontrolle: Die Webhook-Signatur bleibt die zuverlässige Prüfung, dass Inhalt und Absender unverändert sind. Geheimnisse gehören niemals in die URL.

Quellen einschränken

Über den Abschnitt Quellen kannst du einschränken, welche Auslöser den Webhook senden dürfen — zum Beispiel nur die REST-API, nicht aber Änderungen über die Benutzeroberfläche:

Nur API
Webhook reagiert ausschließlich auf Änderungen, die ein anderes System per REST-API gemacht hat. Manuelle CRM-Aktionen erzeugen keinen Aufruf.

Die vollständige Beschreibung steht unter Wo wurde die Änderung ausgelöst?.

Weitere Empfehlungen für Entwickler

Rate-Limit
Begrenze bei Bedarf die Zahl eingehender Aufrufe an deinem Endpunkt. Bei einem Massenimport können viele Webhooks kurz hintereinander eintreffen.
Audit-Log
Logge webhook-id, request_id, event_name und Status — du kannst sie 1:1 mit dem i-Planner-Audit-Log abgleichen, wenn etwas verloren geht.
Strikte Methode
Akzeptiere nur die HTTP-Methode, die du im Webhook konfiguriert hast (i. d. R. POST). Andere Methoden mit 405 ablehnen.
Body-Größe
i-Planner sendet kompakte Payloads. Setze trotzdem eine sinnvolle Obergrenze für eingehende Bodies auf deinem Empfänger, um Missbrauch durch fremde Aufrufer zu vermeiden.
IP-Allowlist optional
Wenn dein Sicherheitsmodell IP-Allowlists vorsieht, sprich i-Planner-Support an. Die primäre Vertrauensprüfung bleibt die HMAC-Signatur, weil sich Egress-IPs ändern können.