API-Sicherheit
Die Buluthat-API steuert Ihre Telefonanlage: Sie startet Anrufe, beendet Gespräche, sendet SMS und verarbeitet Kundennummern. Ein Schlüsselleck bedeutet daher nicht „ein Bericht wird sichtbar“, sondern „von Ihrem Konto aus wird telefoniert“. Diese Seite beschreibt, wie Sie Ihren Schlüssel schützen und welche Schutzmaßnahmen Buluthat für Sie umsetzt.
Basisadresse: https://api.buluthat.com/api/
Die Ebenen auf einen Blick
Jede Anfrage durchläuft nacheinander diese Prüfstufen. Lehnt eine ab, wird die Anfrage nicht verarbeitet und ins Protokoll geschrieben.
| Reihenfolge | Stufe | Was es tut | Fehler |
|---|---|---|---|
| 1 | Brute-Force-Sperre | Versucht eine IP 10 Mal in 20 Minuten einen falschen Schlüssel oder eine falsche Signatur, wird diese IP vorübergehend gesperrt | 429 ip_locked |
| 2 | Body-Limit | Anfrage-Bodys über 5 MB werden nicht gelesen | 413 payload_too_large |
| 3 | Schlüssel | Der Schlüssel wird nur im Header akzeptiert; im System wird nur der SHA-256-Hash gespeichert | 401 invalid_token |
| 4 | Dauer und Kündigung | Ein abgelaufener oder widerrufener Schlüssel wird abgelehnt | 401 token_expired |
| 5 | Zugelassene IP | Erteilen Sie dem Schlüssel die entsprechende Berechtigung oder verwenden Sie den richtigen Schlüssel | 403 ip_not_allowed |
| 6 | Kontostatus | Schlüssel von geschlossenen oder inaktiven Konten funktionieren nicht | 403 account_inactive |
| 7 | Geltungsbereich | Der Schlüssel erhält nur Zugriff auf freigegebene APIs | 403 scope_denied |
| 8 | Signatur | Ist beim Schlüssel „Signierte Anfrage erforderlich“ aktiv, werden HMAC-Signatur, Zeitstempel und einmalige Nonce geprüft | 401 signature_* |
| 9 | Ratenbegrenzung | Minutenlimit pro Schlüssel und für die Kontosumme | 429 rate_limited |
Schnellstart
- Im Panel Konto und Support > API-Schlüssel Öffnen Sie die Seite (nur für den Kontobevollmächtigten sichtbar).
- Neuer Schlüssel: Geben Sie einen Namen vor, markieren Sie nur die benötigten Berechtigungen, tragen Sie die Ausgangs-IP Ihres Servers ein, Signierte Anfrage erforderlichöffnen.
- Kopieren Sie die beiden einmalig angezeigten Werte: API-Schlüssel (
bt_…, bei jeder AnfrageAuthorizationim Header gesendet) und Signaturgeheimnis (bts_…, dient zum Signieren der Anfrage, wird nie gesendet). - Testen Sie die Verbindung:
curl "https://api.buluthat.com/api/autocall.php?action=ping" \
-H "Authorization: Bearer bt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Ist die Signatur verpflichtend, diese Anfrage 401 signature_required kommt zurück; die folgende Anfragesignierung Verwenden Sie eines der Beispiele im Abschnitt.
Schlüssel und Signaturgeheimnis sind im System nicht in lesbarer Form wird nicht gespeichert. Bei Verlust können wir ihn nicht wiederherstellen; Sie erneuern den Schlüssel im Panel.
Geltungsbereiche
Jeder Schlüssel wird mit einem oder mehreren Geltungsbereichen erzeugt. Eine Anfrage an eine API außerhalb des Geltungsbereichs 403 scope_denied kommt zurück.
| Geltungsbereich | APIs, die er öffnet |
|---|---|
autocall | Auto-Call (api/autocall.php). Aus Kompatibilitätsgründen mit älteren Integrationen öffnet er auch die Endpunkte für Sprachassistent, Sprach-Verifizierung und Anrufsteuerung |
call | Anrufsteuerung und Warteschlangen: begin_call, bridge, hangup, transfer, mute, queues, queues_pending, queue_user_list, queue_manage_users, agent_statuses |
voicebot | Sprachassistent (api/voicebot_api.php) und Sprach-Verifizierung |
voice_otp | Sprach-Bestätigungscode (api/voice_otp.php) |
sms | SMS-API (api/sms.php). Kein anderer Geltungsbereich hat Zugriff auf SMS |
bridge | Live-Telefonanlagendaten (api/crm_bridge.php): Live-Anrufe, Agentenstatus, Gesprächsaufzeichnungen, Tonaufnahmen, Sperrliste, Ansagen. Nur das Konto des Schlüssels; gesendete tenant_id wird ignoriert |
* | Alle APIs. Nur wenn wirklich nötig |
Grundsatz: ein eigener Schlüssel pro Integration, jedem Schlüssel die geringsten Rechte. Gelangt der SMS-Schlüssel Ihres Onlineshops nach außen, kann ein Angreifer keine Anrufe starten; Sie widerrufen nur diesen Schlüssel.
Schlüssel senden
Schlüssel im Header wird gesendet:
Authorization: Bearer bt_xxxxxxxx
Authorization für Umgebungen, die den Header nicht setzen können X-Api-Key: bt_xxxxxxxx wird ebenfalls akzeptiert.
Schlüssel in der URL (?key=)
?key=bt_… Format bei neuen Schlüsseln ist deaktiviert und 401 query_key_disabled kommt zurück. URLs landen in Webserver-Protokollen, Proxy-Aufzeichnungen, im Browserverlauf und Referer landet im Header; darüber gelangt der Schlüssel nach außen. Nur für ein altes System, das keinen Header senden kann, in den Schlüsseleinstellungen "Schlüssel in der URL akzeptieren" geöffnet werden. Das Panel markiert diese Schlüssel rot ?key= mit dem Badge an.
Bei vor V54 erzeugten Schlüsseln wurde diese Berechtigung offen gelassen, damit ältere Integrationen nicht abreißen. Schließen Sie sie, nachdem Sie Ihre Integration auf den Header umgestellt haben.
Zugelassene IP
In den Schlüsseleinstellungen Zugelassene IP-Adressen Im Feld wird pro Zeile eine IP oder ein CIDR-Block eingetragen:
85.111.89.220
10.20.0.0/24
2a01:4f8:c0c:1234::/64
Ist die Liste leer, wird jede IP akzeptiert. Ist sie gefüllt, wird eine Anfrage von einer Adresse außerhalb der Liste auch bei richtigem Schlüssel 403 ip_not_allowed kommt zurück. Die einzutragende Adresse ist die, die die API aufruft ist die Ausgangs-IP Ihres Servers (nicht die Ihres eigenen Rechners). Wenn Sie unsicher sind, prüfen Sie im Protokoll die IP-Spalte der Anfrage von diesem Server.
Anfragesignierung
Die Signatur sorgt dafür, dass selbst bei Übernahme des Schlüssels keine Anfragen gestellt werden können: Der Angreifer braucht zusätzlich das Signaturgeheimnis, das bei keiner Anfrage über das Netz geht. Die Signatur außerdem:
- Sperrt den Body: ändert sich auch nur ein Zeichen im Pfad, stimmt die Signatur nicht.
- Verhindert die Wiedergabe erneut: jede Nonce wird nur einmal akzeptiert; eine abgefangene Anfrage kann kein zweites Mal gesendet werden.
- Lehnt veraltete Anfragen ab: weicht der Zeitstempel um mehr als ±5 Minuten von der Serverzeit ab, wird die Anfrage abgelehnt.
Beim Schlüssel Signierte Anfrage erforderlich Ist die Option aktiv, muss jede Anfrage signiert sein. Auch wenn sie deaktiviert ist, wird die Signatur geprüft, sobald Sie Signatur-Header mitsenden; eine falsche Signatur geht nicht stillschweigend durch.
Header
| Absenderkennung | Wert |
|---|---|
Authorization | Bearer bt_… |
X-Bt-Timestamp | Unix-Zeit, Sekunden (z. B. 1790802088) |
X-Bt-Nonce | Bei jeder Anfrage neu, 16-64 Zeichen A-Z a-z 0-9 _ - (z. B. 32 hex) |
X-Bt-Signature | v1= + die Signatur in Kleinbuchstaben-Hex |
Kanonischer Text
Der signierte Text, dazwischen \n (LF) sind es sechs Zeilen:
v1
POST
/api/sms.php?action=send
1790802088
9f86d081884c7d659a2feaa0c55ad015
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
| Zeile | Inhalt |
|---|---|
| 1 | Version, fest v1 |
| 2 | HTTP-Methode, Großbuchstaben (GET, POST) |
| 3 | Pfad und Query-String, so, wie die Anfrage gesendet wurde (/api/sms.php?action=send). Domain und Schema sind nicht enthalten |
| 4 | X-Bt-Timestamp Wert |
| 5 | X-Bt-Nonce Wert |
| 6 | SHA-256-Hash des Bodys, Hex in Kleinbuchstaben. Bei Anfragen ohne Body und multipart/form-data Bei (Datei-Upload-)Anfragen der Hash des leeren Textes: e3b0c442…b855 |
Signatur: hex( HMAC-SHA256( anahtar = imza_sırrı, mesaj = kanonik_metin ) )
PHP
function buluthat_request(string $method, string $url, string $token, string $secret, ?array $data = null): array
{
$body = $data === null ? '' : json_encode($data, JSON_UNESCAPED_UNICODE);
$p = parse_url($url);
$uri = ($p['path'] ?? '/') . (isset($p['query']) ? '?' . $p['query'] : '');
$ts = (string)time();
$nonce = bin2hex(random_bytes(16));
$canonical = implode("\n", ['v1', strtoupper($method), $uri, $ts, $nonce, hash('sha256', $body)]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'X-Bt-Timestamp: ' . $ts,
'X-Bt-Nonce: ' . $nonce,
'X-Bt-Signature: v1=' . hash_hmac('sha256', $canonical, $secret),
],
]);
if ($body !== '') {
curl_setopt($ch, CURLOPT_POSTFIELDS, $body); // imzalanan gövdenin AYNISI
}
$res = json_decode((string)curl_exec($ch), true) ?: [];
curl_close($ch);
return $res;
}
$token = getenv('BULUTHAT_TOKEN'); // bt_...
$secret = getenv('BULUTHAT_SECRET'); // bts_...
print_r(buluthat_request('POST', 'https://api.buluthat.com/api/sms.php?action=send', $token, $secret, [
'header' => 'FIRMAM', 'message' => 'Siparişiniz kargoya verildi.', 'phones' => ['05321234567'],
]));
Auch die fertigen Clients signieren: buluthat-autocall-client.php und buluthat-voice-otp-client.php im vierten Parameter ['signing_secret' => 'bts_…'] erhält.
Node.js
const crypto = require('crypto');
async function buluthatRequest(method, url, token, secret, data) {
const body = data === undefined ? '' : JSON.stringify(data);
const u = new URL(url);
const ts = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomBytes(16).toString('hex');
const canonical = ['v1', method.toUpperCase(), u.pathname + u.search, ts, nonce,
crypto.createHash('sha256').update(body).digest('hex')].join('\n');
const signature = crypto.createHmac('sha256', secret).update(canonical).digest('hex');
const res = await fetch(url, {
method,
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'X-Bt-Timestamp': ts,
'X-Bt-Nonce': nonce,
'X-Bt-Signature': `v1=${signature}`,
},
body: body || undefined,
});
return res.json();
}
buluthatRequest('GET', 'https://api.buluthat.com/api/voice_otp.php?action=status&id=42',
process.env.BULUTHAT_TOKEN, process.env.BULUTHAT_SECRET).then(console.log);
Python
import hashlib, hmac, json, os, secrets, time, urllib.parse
import requests
def buluthat_request(method, url, token, secret, data=None):
body = b"" if data is None else json.dumps(data, ensure_ascii=False).encode("utf-8")
u = urllib.parse.urlsplit(url)
uri = u.path + ("?" + u.query if u.query else "")
ts = str(int(time.time()))
nonce = secrets.token_hex(16)
canonical = "\n".join(["v1", method.upper(), uri, ts, nonce, hashlib.sha256(body).hexdigest()])
sig = hmac.new(secret.encode(), canonical.encode("utf-8"), hashlib.sha256).hexdigest()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"X-Bt-Timestamp": ts,
"X-Bt-Nonce": nonce,
"X-Bt-Signature": f"v1={sig}",
}
return requests.request(method, url, data=body or None, headers=headers, timeout=30).json()
print(buluthat_request("POST", "https://api.buluthat.com/api/autocall.php?action=add_leads",
os.environ["BULUTHAT_TOKEN"], os.environ["BULUTHAT_SECRET"],
{"campaign_id": 12, "leads": [{"phone": "05321234567", "name": "Ayşe Yılmaz"}]}))
Kommandozeile (bash + openssl)
TOKEN=bt_xxx; SECRET=bts_xxx
URI='/api/autocall.php?action=ping'
TS=$(date +%s); NONCE=$(openssl rand -hex 16)
BODYHASH=$(printf '' | openssl dgst -sha256 -hex | awk '{print $NF}')
SIG=$(printf 'v1\nGET\n%s\n%s\n%s\n%s' "$URI" "$TS" "$NONCE" "$BODYHASH" \
| openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $NF}')
curl "https://api.buluthat.com$URI" -H "Authorization: Bearer $TOKEN" \
-H "X-Bt-Timestamp: $TS" -H "X-Bt-Nonce: $NONCE" -H "X-Bt-Signature: v1=$SIG"
Warum stimmt die Signatur nicht?
| Symptom | Grund |
|---|---|
signature_invalid nur bei POST | Der signierte Body und der gesendete Body unterscheiden sich. JSON einmalig erzeugen, dieselbe Variable in Zusammenfassung und Anfrage übergeben |
signature_invalid Bei einer Abfrage mit türkischen Zeichen | Sie haben den Pfad selbst zusammengesetzt und anders kodiert. Verwenden Sie in der Signatur den Pfad und die Query aus der URL, die der Client tatsächlich gesendet hat (parse_url / new URL()) |
signature_expired | Die Uhr Ihres Servers geht falsch. NTP (timedatectl set-ntp true) öffnen; Toleranz ±300 Sek. |
signature_replayed | Dieselbe Nonce wurde ein zweites Mal gesendet. Bei einem erneuten Versuch (Retry) Nonce und Zeitstempel neu erzeugen und neu signieren |
signature_required | Beim Schlüssel ist eine Signatur erforderlich, aber die Header fehlen |
signature_not_configured | Der Schlüssel hat kein Signaturgeheimnis; erzeugen Sie im Panel ein „Neues Signaturgeheimnis“ |
Fehlercodes
Authentifizierungs- und Sicherheitsfehler sind bei allen JSON-Endpunkten gleich code kommt mit den Werten zurück. Die Endpunkte für Anrufsteuerung und Warteschlangen (Verimor-kompatibel) liefern denselben HTTP-Code mit einer Klartextmeldung.
| HTTP | code | Was zu tun ist |
|---|---|---|
| 401 | missing_token | Authorization: Bearer … fügen Sie den Header hinzu |
| 401 | invalid_token | Schlüssel falsch, widerrufen oder nicht vorhanden. Nicht erneut versuchen, korrigieren Sie die Einstellung |
| 401 | token_expired | Schlüssel im Panel erneuern |
| 401 | query_key_disabled | Senden Sie den Schlüssel im Header statt in der URL |
| 401 | signature_* | Siehe die Tabelle oben |
| 403 | ip_not_allowed | Tragen Sie die Ausgangs-IP Ihres Servers in die Liste des Schlüssels ein |
| 403 | scope_denied | Beim Schlüssel |
| 403 | account_inactive | Konto gesperrt; wenden Sie sich an den Support |
| 403 | module_disabled | Der entsprechende Dienst ist in Ihrem Paket nicht aktiviert |
| 413 | payload_too_large | Teilen Sie die Anfrage in Teile auf (z. B. add_leads höchstens 5.000 Einträge) |
| 429 | rate_limited / tenant_rate_limited | Retry-After warten Sie bis |
| 429 | ip_locked | Von dieser IP gingen viele fehlerhafte Versuche ein; korrigieren Sie die fehlerhafte Konfiguration, die Sperre hebt sich von selbst auf |
Beispiel für eine Fehlerantwort:
{ "ok": false, "error": "Bu anahtarın bu API için yetkisi yok.", "code": "scope_denied", "request_id": "df5fca3a599653f6" }
Ratenbegrenzungen
| Limit | Standard |
|---|---|
| Pro Schlüssel | 120 Anfragen pro Minute (in den Schlüsseleinstellungen senkbar) |
| Summe aller Schlüssel des Kontos | 600 Anfragen pro Minute |
Agentenstatus (agent_statuses) | zusätzlich 2 Anfragen pro Minute und Konto |
Bei jeder erfolgreichen Antwort kommt das verbleibende Kontingent in den Headern:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1790802120
429 bei Erhalt Retry-After (Sekunden) abwarten. Bei Netzwerkfehlern und 5xx verwenden Sie für exponentiellen Backoff (1 Sek., 2 Sek., 4 Sek. … höchstens 5 Versuche). 401/403 Fehler nicht erneut versuchen: das ist ein Konfigurationsfehler, Versuche lösen die Brute-Force-Sperre aus.
Schlüssel fehlt, ist ungültig oder abgelaufen
Erneuern Sie Schlüssel alle 90-180 Tage, bei Weggang von Mitarbeitern oder bei Verdacht auf ein Leck. Unterbrechungsfreier Wechsel:
- API-Schlüssel > betreffender Schlüssel > Einstellungen > Schlüssel erneuern. Wählen Sie „Alter Schlüssel läuft noch 24 Stunden“.
- Mit denselben Einstellungen werden ein neuer Schlüssel und ein neues Signaturgeheimnis erzeugt und einmalig auf dem Bildschirm angezeigt.
- Aktualisieren Sie Ihre Integration mit den neuen Werten.
- Im Protokoll das Präfix des alten Schlüssels (
bt_7820d84…) nicht mehr angezeigt wird, warten Sie; nach Ablauf der Frist schließt sich der alte Schlüssel von selbst.
Bei Verdacht auf ein Leck Wählen Sie „Alten Schlüssel sofort schließen“; Anfragen mit dem alten Schlüssel werden sofort abgelehnt.
Anfrageprotokoll
Unterhalb der Seite „API-Schlüssel“ Anfrageprotokoll zeigt jede Anfrage: Zeitpunkt, Schlüsselpräfix, IP, Endpunkt und Aktion, HTTP-Status, Fehlercode, Dauer, signiert oder nicht. Die Zusammenfassung der letzten 24 Stunden (Anfragen, Fehler, Ratenbegrenzung, Authentifizierungsfehler, signierte Anfragen, Anzahl verschiedener IPs) steht oben auf der Seite. Einträge werden 90 Tage aufbewahrt.
In jeder Antwort X-Request-Id gibt es. Geben Sie diesen Wert in der Supportanfrage an; wir finden Ihre Anfrage sofort im Protokoll. Geben Sie den Schlüssel oder das Signaturgeheimnis niemals in Supportanfragen, E-Mails oder Screenshots weiter.
Sehen Sie Anfragen von einer unbekannten IP oder zu unerwarteten Zeiten, erneuern Sie den Schlüssel sofort mit „Alten sofort schließen“.
Einrichtung des Byfix-CRM
Das Byfix-CRM verbindet sich mit zwei getrennten Identitäten mit Buluthat:
| Einstellung (CRM) | Wert |
|---|---|
| Einstellungen > Auto-Call > API-Schlüssel | Bei Buluthat erzeugte bt_… Schlüssel (Geltungsbereich: autocall + voicebot + voice_otp + call) |
| Einstellungen > Auto-Call > Signaturgeheimnis | Desselben Schlüssels bts_… Geheimnis. Ist es gesetzt, wird jede Anfrage des CRM an Buluthat signiert |
| VoIP-Einstellungen > Buluthat API Token | Live-Bildschirm / CDR-Brücke (crm_bridge); wird vom Buluthat-Team vergeben und ist vom obigen Schlüssel getrennt |
Empfohlene Reihenfolge: den Schlüssel Signierte Anfrage erforderlich deaktiviert erzeugen, im CRM Schlüssel und Geheimnis eintragen, im Protokoll die Anfragen imzalı mit dem Badge ankommt, machen Sie dann im Schlüssel die Signatur verpflichtend. Fügen Sie dem Schlüssel auch die IP des CRM-Servers hinzu.
Click-to-call (begin_call) sendet den Schlüssel nun im Header statt in der URL. Nach dem CRM-Update können Sie bei alten Schlüsseln die Berechtigung „Schlüssel in der URL“ deaktivieren.
ByCRM-Einrichtung
Im ByCRM jede Firma bei Buluthat mit eigenem Schlüssel angebunden; Firmen können die Daten der jeweils anderen nicht sehen.
- Mit dem Konto der Firma im Buluthat-Panel API-Schlüssel > Neuer Schlüssel: Berechtigungen Live-Telefonanlagendaten, Anrufsteuerung und Warteschlangen, Auto-Call (falls verwendet Sprachassistent, Sprach-Bestätigungscode). Tragen Sie die IP des ByCRM-Servers ein.
- ByCRM > Integrationen > Buluthat:
| Feld | Wert |
|---|---|
| Buluthat API Token | bt_… |
| Signaturgeheimnis | bts_… |
| Bridge Token | derselbe bt_… Schlüssel |
| CRM Bridge URL | https://api.buluthat.com/api/crm_bridge.php |
| Autocall URL | https://api.buluthat.com/api/autocall.php |
| Buluthat Tenant ID / PBX Server ID | Wird nicht verwendet; es kommen die Daten des Kontos, zu dem der Schlüssel gehört |
- Testen Sie den Live-Bildschirm und Click-to-call, im Protokoll
imzalıdie Badges, machen Sie dann im Schlüssel Signierte Anfrage erforderlichöffnen.
Da der Live-Bildschirm die Brücke alle paar Sekunden abfragt, gilt für Brückenanfragen eine eigene, großzügigere Ratenbegrenzung (1.200 pro Minute und Schlüssel); ins Protokoll werden nur fehlerhafte Brückenanfragen geschrieben.
Webhooks verifizieren
Auch die Webhooks, die Buluthat Ihnen sendet, sind signiert (X-Buluthat-Signature: sha256=…). Prüfen Sie auf Ihrem Server die Signatur Rohbody verarbeiten Sie keinen Webhook ohne Verifizierung über X-Buluthat-Delivery verarbeiten Sie dieselbe Zustellung nicht zweimal. Einzelheiten: Webhooks.
Sicherheits-Checkliste
- [ ] Jede Integration hat ihren eigenen Schlüssel, nur mit den nötigen Geltungsbereichen
- [ ] Schlüssel stehen nicht im Code, sondern in Umgebungsvariablen oder einer Geheimnisverwaltung (
.envWird nicht in Git eingecheckt) - [ ] Der Schlüssel liegt nur serverseitig; nicht im Browser-JavaScript, nicht in der Mobil-App, nicht in einem Excel-Makro
- [ ] Die Liste zugelassener IPs ist ausgefüllt
- [ ] „Signierte Anfrage erforderlich“ ist aktiv
- [ ] Schlüssel in der URL (
?key=) deaktiviert - [ ] Es gibt ein Ablaufdatum oder eine Erneuerungserinnerung im Kalender
- [ ] Der Client prüft das TLS-Zertifikat (
CURLOPT_SSL_VERIFYPEERaktiv); bei deaktivierter Verifizierung kann jemand dazwischen die Anfrage lesen und verändern - [ ] Die Serverzeit ist per NTP synchronisiert
- [ ] Die Webhook-Signatur wird verifiziert
- [ ] Das Protokoll wird monatlich geprüft; Schlüssel, auf die ausgeschiedene Mitarbeiter Zugriff hatten, wurden erneuert
Meldung einer Sicherheitslücke
Wenn Sie glauben, eine Sicherheitslücke in der Buluthat-API gefunden zu haben, melden Sie sich über das Support-Center im Panel „Sicherheitsmitteilung“ Eintrag mit dem Thema eröffnen. Beschreiben Sie, wie Sie die Lücke reproduziert haben, und falls vorhanden X-Request-Id fügen Sie die Werte hinzu. Wir bitten Sie, die Einzelheiten nicht zu teilen, bis wir die Meldung geprüft und behoben haben.
