Werden Zugangsgrenzen für API-Subdomains tatsächlich durchgesetzt?
API-Subdomain-Zugangsgrenzen verhindern, dass Tokens über Weiterleitungen oder lockeren Client-Code benachbarte, regionale, Vanity- und Mandanten-Hosts erreichen.

Ein Hostname ist kein Hinweis auf Eigentum. Er ist Teil der Zielidentität und entscheidet, wohin ein API-Zugangsschlüssel gesendet wird. Wenn ein Client einen Bearer-Token besitzt und api.example.com, files.example.com, api.eu.example.com und customer.example.com wegen ihres gemeinsamen Suffixes für im Grunde gleichwertig hält, hat der Client bereits die gefährliche Entscheidung getroffen.
Dieser Fehler versteckt sich hinter einer scheinbar übersichtlichen Architektur. Ein Unternehmen kann jeden Namen unter einer übergeordneten Domain besitzen. DNS kann mehrere Namen an denselben Load Balancer senden. Zertifikate können für alle Namen gelten. Nichts davon bedeutet, dass ein für eine API ausgestellter Zugangsschlüssel einen anderen Hostnamen erreichen sollte. Zugangsdaten brauchen eine ausdrückliche Zielregel. Für diese Regel braucht es Tests, die fehlschlagen, wenn sie später unbemerkt erweitert wird.
Hostnamen übernehmen kein Vertrauen von einer übergeordneten Domain
api.example.com und admin.example.com können dieselbe registrierbare Domain haben, sind aber getrennte Origins. Ein Origin umfasst Schema, Host und Port. Auch https://api.example.com und https://api.example.com:8443 sind getrennte Origins. Das ist wichtig, weil ein Client das Netzwerkziel anhand dieser Autorität auswählt, nicht anhand der Marketingbeziehung zwischen den Diensten.
RFC 9110 definiert einen HTTP-Authentifizierungsschutzbereich anhand des Origins und, falls vorhanden, einer Realm. Der Standard warnt außerdem davor, sich allein auf Realms zu verlassen, weil dadurch Zugangsdaten anderen Ressourcen auf einem Origin zugänglich werden können. Wenn verschiedene Parteien getrennt werden müssen, empfiehlt er separate Hostnamen oder Ports. Das ist ein nützlicher Hinweis, aber keine Erlaubnis, alle Namen unter einem Suffix als einen einzigen Schutzbereich zu behandeln.
Ingenieure vermischen häufig drei verschiedene Begriffe:
- Eine übergeordnete Domain benennt einen DNS-Namensraum.
- Eine Site gruppiert verwandte Web-Origins für bestimmte Browser-Sicherheitsregeln.
- Ein Origin identifiziert ein Schema, einen Host und einen Port für ein HTTP-Ziel.
Nur die ersten beiden lassen Subdomains verbunden wirken. Dein API-Zugangsschlüssel-Verteiler sollte das dritte Konzept verwenden.
Das gilt auch, wenn der Aussteller des Zugangsschlüssels einen breiten aud-Claim in einen Token schreibt. Ein breiter Audience-Claim sagt dem empfangenden Dienst, was er akzeptieren darf. Er weist deinen Client nicht an, den Token jedem Endpoint anzubieten, der ihn möglicherweise akzeptiert. Der Absender bleibt dafür verantwortlich, die Verteilung zu minimieren.
Ich habe diesen Fehler immer wieder in ähnlicher Form gesehen. Ein Team startet mit einem einzelnen Endpoint, fügt api.staging.example.com hinzu und behält einen Helfer namens getApiKey(). Sechs Monate später wird der Helfer von fünf Diensten verwendet. Er hat kein Host-Argument, keine Allowlist und keinen Grund, einen Aufruf abzulehnen. Der Schlüssel wurde nicht durch einen exotischen Exploit unsicher. Er wurde unsicher, weil der Code nicht mehr festhielt, dass der Schlüssel zu einem bestimmten Ziel gehörte.
Mache die Hostbindung in der Konfiguration und bei Code-Reviews sichtbar. Ein Zugangsschlüssel-Auswähler, der nur einen Namen für den Zugangsschlüssel akzeptiert, hat bereits die Hälfte seiner Eingabe verloren.
Die vier Hostnamen-Formen scheitern auf unterschiedliche Weise
Benachbarte, Vanity-, regionale und kundenspezifische Domains brauchen eigene Testfälle, weil sie aus unterschiedlichen Gründen problematisch werden. Eine vage Zusicherung, dass ein Token innerhalb „unserer Domains“ bleibt, wird mindestens eine dieser Varianten übersehen.
Ein benachbarter Host liegt neben dem vorgesehenen Host: metrics.example.com statt api.example.com. Das kann einen gemeinsamen Ingress, einen alten Dienst oder ein internes Werkzeug offenlegen, das Produktionszugangsdaten nie sehen sollte. Besonders gefährlich wird ein solcher Host, wenn ein generischer Proxy Header unverändert an ein Upstream-System weiterleitet, das über die Routing-Konfiguration ausgewählt wurde.
Ein Vanity-Host ist ein freundlicher Alias wie api.brand.example oder developer.example.com. Anbieter führen solche Namen bei Umbenennungen, Übernahmen oder Migrationen ein. Der Alias kann an einem anderen Edge enden, eine andere Telemetrie verwenden oder auf einen kanonischen Host weiterleiten. Gewähre ihm keinen Zugriff auf Zugangsdaten, nur weil du einmal eine Weiterleitung in einem Browser gesehen hast.
Ein regionaler Host verändert den Standort und häufig auch den Besitz des Dienstes: api.us.example.com, api.eu.example.com oder api.ap-southeast.example.com. Die Anfrage kann bereits Geschäftsdaten enthalten, bevor die Anwendung den Token ablehnt. Eine 401-Antwort beweist nicht, dass es akzeptabel war, die Zugangsdaten und den Body an diese Region zu senden.
Ein kundenspezifischer Host verschärft Fehler in Multi-Tenant-Systemen: acme.vendor.example und northwind.vendor.example können über dieselbe Infrastruktur aufgelöst werden, doch jeder Hostname steht für eine Mandantengrenze. Ein Token, der an beiden funktioniert, kann für eine zentrale Steuerung absichtlich so breit sein. Er darf niemals zum Standard-Zugangsschlüssel für mandantenspezifische Anfragen werden.
Nimm jede Kategorie in dein Verzeichnis auf. Fasse sie nicht in einem Feld namens allowed_domains zusammen und nimm nicht an, dass eine Wildcard die Richtlinie einfacher macht. Die Wildcard verschiebt die schwierige Entscheidung nur aus dem Sichtfeld.
Binde die Auswahl des Zugangsschlüssels an die vollständige Autorität
Ein sicherer Client ordnet einer Anfrageautorität genau einen Datensatz für Zugangsdaten zu und lehnt die Anfrage ab, wenn kein Datensatz passt. Die vollständige Autorität umfasst Schema, normalisierten Hostnamen und den tatsächlich verwendeten Port. Bei einer gewöhnlichen HTTPS-API auf Port 443 kann die sichtbare Konfiguration einfach bleiben. Die Implementierung muss einen unerwarteten Port aber trotzdem ablehnen, statt den Token stillschweigend wiederzuverwenden.
Ein brauchbares Verzeichnis sieht so aus:
credentials:
billing-production:
allowed:
- https://api.billing.example.com:443
header: Authorization
scheme: Bearer
telemetry-eu:
allowed:
- https://ingest.eu.example.net:443
header: X-Write-Key
Es geht nicht um YAML. Entscheidend ist, dass der Name des Tokens nicht für sich allein steht. billing-production hat ein ausdrücklich festgelegtes Ziel. telemetry-eu kann nicht an einen US-Endpoint gelangen, nur weil ein Aufrufer eine Hostnamen-Zeichenfolge geändert hat.
Vermeide dieses Muster:
const headers = {
Authorization: `Bearer ${process.env.PRODUCTION_API_TOKEN}`
};
await fetch(userSuppliedUrl, { headers });
Der Code verbindet ein uneingeschränktes Ziel mit einer privilegierten Zugangsinformation. Entwickler verteidigen das manchmal mit dem Hinweis, dass die URL aus einer vertrauenswürdigen Konfigurationsdatei stammt. Auch diese Datei ist eine Eingabegrenze. Deployment-Werkzeuge, Umgebungsüberschreibungen, Pull Requests, Feature-Flags und ein kompromittierter Build-Job können sie verändern.
Verwende einen Request-Builder, der authentifizierte Anfragen erst erstellt, nachdem er ein normalisiertes Ziel gefunden hat. Die Normalisierung des Hostnamens sollte streng und unspektakulär bleiben:
- Analysiere die URL mit einem echten URL-Parser, nicht mit Zeichenketten- oder Suffixprüfungen.
- Verlange
https:, sofern keine dokumentierte Ausnahme für die lokale Entwicklung existiert. - Schreibe den Hostnamen klein und kanonisiere ihn über den Parser.
- Vergleiche Schema, Host und Port mit exakt freigegebenen Autoritäten.
- Füge den Authentifizierungs-Header erst hinzu, wenn der Abgleich erfolgreich war.
Schreibe nicht host.endsWith("example.com"). Dadurch wird notexample.com akzeptiert. Repariere das auch nicht einfach mit endsWith(".example.com") und erkläre die Arbeit für erledigt. Dieser Ausdruck gibt weiterhin jeder aktuellen und zukünftigen Subdomain den Token, auch Namen, die an einen Kunden, einen Anbieter oder eine vergessene Entwicklungsumgebung delegiert wurden.
Die Unterscheidung zwischen der Autorisierung des Ziels und der Autorisierung des Zugangsschlüssels muss klar bleiben. Eine empfangende API kann einen nicht passenden Token ablehnen. Dein Absender sollte verhindern, dass der Token diese API überhaupt erreicht. Die erste Kontrolle begrenzt die Offenlegung. Die zweite entscheidet über den Zugriff. Du brauchst beide.
Eine Weiterleitung ist ein neues Ziel, keine Fortsetzung der alten Anfrage
Die Behandlung von Weiterleitungen schafft eine zweite Grenze für Zugangsdaten. Der erste Host kann genehmigt sein und anschließend einen Location-Header mit einem Vanity-Namen, einem regionalen Endpoint, Objektspeicher oder einem Host zurückgeben, den ein Angreifer über eine offene Weiterleitung kontrolliert. Folgt der Client automatisch, muss er die Zielautorisierung erneut ausführen, bevor er Zugangsdaten oder den Request-Body sendet.
libcurl macht den Unterschied besonders deutlich. Standardmäßig sendet es bei Weiterleitungen keine intern erzeugten Authentifizierungs- oder ausdrücklich gesetzten Cookie-Header an einen anderen Host. Die Option CURLOPT_UNRESTRICTED_AUTH ändert dieses Verhalten und kann Zugangsdaten an Hosts senden, die durch Weiterleitungsantworten ausgewählt wurden. Das curl-Projekt warnt, dass benutzerdefinierte Header besondere Vorsicht erfordern, weil die Bibliothek nicht erkennen kann, welche beliebigen Header Geheimnisse enthalten.
Gerade dieses Detail überrascht auch erfahrene Teams. Sie testen die Basic-Authentifizierung mit einem Standard-Client und sehen, dass sich eine hostübergreifende Weiterleitung sicher verhält. Dann verwendet ihre Produktionsintegration X-Api-Key, Authorization: Bearer oder X-Signature als generischen Header. Eine Bibliothek kann diesen Header beibehalten, wenn die Anwendung ihn nicht entfernt. Ein bestandener Test für einen Authentifizierungsmechanismus sagt nichts über einen anderen aus.
Behandle Weiterleitungen je nach Anfrageklasse:
- Lehne Weiterleitungen bei Schreibvorgängen ab, sofern der API-Vertrag sie nicht verlangt.
- Prüfe bei Lesevorgängen jedes Weiterleitungsziel und erstelle die Header anhand des für das Ziel genehmigten Datensatzes neu.
- Erstelle bei signierten Anfragen die Signatur erst nach der Autorisierung des endgültigen Ziels neu. Leite niemals eine für den ersten Host erstellte Signatur weiter.
- Leite bei Uploads den ursprünglichen Authorization-Header nicht an eine vorab signierte Speicher-URL weiter. Die Query-Signatur oder die Formularfelder enthalten bereits die begrenzte Berechtigung, die dieser Storage-Endpoint erwartet.
Ein Weiterleitungstest muss die Anfrage untersuchen, die am zweiten Server ankommt. Nur den finalen Statuscode zu prüfen, reicht nicht. Eine 200-Antwort von einem harmlosen Testempfänger kann verbergen, dass dieser den Produktions-Header erhalten hat, den du schützen wolltest.
Für Wiederholungen gilt dieselbe Disziplin. Manche HTTP-Wrapper bauen Anfragen aus einer zwischengespeicherten Header-Map neu auf. Wenn eine Wiederholung durch Service Discovery zu einer neuen Autorität führt, verwerfe die zwischengespeicherte Map und frage den Zugangsschlüssel-Auswähler erneut. Header wiederzuverwenden ist schneller. So verschwindet aber auch der Kontext des Ziels.
Baue eine negative Testumgebung, bevor du der Allowlist vertraust
Der wichtige Test ist negativ: Ein Zugangsschlüssel muss am vorgesehenen Host auftauchen und darf nicht an jedem plausiblen falschen Host erscheinen. Du kannst das mit zwei lokalen HTTPS-Testservern ausführen. Der Empfänger darf jedoch nur erfassen, ob sensible Header vorhanden sind und wie sie heißen. Verwende in Testprotokollen keine echten Werte.
Für eine Prüfung auf Shell-Ebene kannst du harmlose Namen mit der curl-Option --resolve lokalen Servern zuordnen und einen Wegwerf-Token verwenden. Starte einen Empfänger auf Port 8443 für den genehmigten Host und einen zweiten auf Port 9443 für den benachbarten Host. Jeder Empfänger sollte einen Datensatz wie diesen ausgeben:
host=api.test.example
path=/v1/ping
authorization=present
x-api-key=absent
Der Empfänger des benachbarten Hosts sollte das umgekehrte Ergebnis ausgeben:
host=metrics.test.example
path=/v1/ping
authorization=absent
x-api-key=absent
Führe anschließend den tatsächlichen HTTP-Client-Wrapper aus, nicht eine isolierte Version seiner Logik. Eine curl-Prüfung kann die grundlegende Verdrahtung sichtbar machen:
curl --silent --show-error \\
--resolve api.test.example:8443:127.0.0.1 \\
--header 'Authorization: Bearer test-token-do-not-use' \\
https://api.test.example:8443/v1/ping
Dieser Befehl setzt den Header absichtlich auf der Anfrage. Er beweist daher nur, was der Empfänger protokolliert. Er beweist nicht, dass deine Anwendung Zugangsdaten sicher auswählt. Dein Anwendungstest sollte die normale Funktion request() mit derselben genehmigten Autorität aufrufen, dann mit jeder falschen Autorität wiederholt werden und prüfen, dass vor dem Öffnen einer Verbindung ein Fehler ausgelöst wird.
Verwende eine Matrix, die Entscheidungen erzwingt, die sonst oft stillschweigend vorausgesetzt werden:
| Angeforderte Autorität | Erwartetes Verhalten bei Zugangsdaten |
|---|---|
https://api.test.example | Den vorgesehenen Test-Zugangsschlüssel senden |
https://metrics.test.example | Vor dem Senden ablehnen |
https://api.eu.test.example | Ablehnen, sofern nicht separat konfiguriert |
https://tenant-a.test.example | Ablehnen, sofern die Mandantenbindung nicht ausdrücklich festgelegt ist |
| Genehmigter Host leitet an benachbarten Host weiter | Nur nach erneuter Autorisierung folgen, normalerweise ohne die ursprünglichen Zugangsdaten |
Verwende für diesen Test keinen externen Request-Bin-Dienst. Du würdest deinem Team beibringen, Testgeheimnisse an einen Dritten zu senden, während es prüft, ob es Geheimnisse an Dritte sendet. Ein lokaler Empfänger ist trivial und hält die Belege unter deiner Kontrolle.
Nimm die Matrix in die kontinuierliche Integration auf. Ein Unit-Test für isAllowedHost() ist hilfreich. Ein Integrationstest erfasst jedoch die häufige Regression: Jemand fügt einer tieferen HTTP-Schicht einen Standard-Header hinzu, nachdem die Hostprüfung bereits stattgefunden hat.
Browserregeln gelten nicht automatisch für Agenten
Die Sprache des Browsers führt in Agenten- und Backend-Code zu falschen Annahmen. „Same-Site“ kann Subdomains einschließen, „Same-Origin“ dagegen nicht. MDN verwendet https://example.org und https://login.example.org als Beispiel für zwei Origins, die zur selben Site gehören. Diese Unterscheidung gibt es auch deshalb, weil eine kompromittierte Subdomain einen benachbarten Host über Same-Site-Pfade angreifen kann.
Fetch verwendet standardmäßig credentials: "same-origin". Dadurch werden Zugangsdaten bei Cross-Origin-Anfragen nicht automatisch mitgesendet. Ein Entwickler kann diesen Standard sehen, einen Frontend-Aufruf testen und daraus schließen, dass ein Bearer-Token nicht von einer Subdomain zu einer anderen gelangen kann. Diese Schlussfolgerung gilt nicht für serverseitigen Code. Ein Backend-Fetch-Wrapper kann jeden Header anhängen, den sein Autor vorgibt. Eine CLI kann dasselbe tun. Ein autonomer Agent kann ein generisches HTTP-Werkzeug mit URL und Headern aufrufen, sofern das Werkzeug die Zugangsdaten nicht außerhalb seiner Reichweite hält.
CORS behebt das nicht. CORS steuert hauptsächlich, ob JavaScript im Browser eine Antwort lesen kann. Es macht aus einem breit angelegten serverseitigen Header-Injektor keinen sicheren Zugangsschlüssel-Verteiler. Bei manchen Browseranfragen kann der Browser die Zugangsdaten senden und anschließend verhindern, dass das Skript die Antwort sieht. Das ist keine akzeptable Kontrolle zur Vermeidung von Datenverlust.
Cookies sorgen für eine weitere Verwechslung. Domain-Attribute von Cookies können erlauben, dass ein Cookie Subdomains erreicht, während hostgebundene Cookies das nicht tun. Bearer-Header haben keinen vergleichbaren eingebauten Domainbereich. Wenn dein Client Authorization anhängt, hat er für diese Anfrage eine ausdrückliche Entscheidung getroffen. Übertrage keine Cookie-Denkmodelle auf API-Schlüssel.
Kundendomains brauchen eine Ausstellergrenze, keine Namenskonvention
Eine zentrale API kann berechtigt sein, viele Kunden-Endpoints aufzurufen. Sie braucht dafür aber Zugangsdaten, aus denen hervorgeht, warum der Aufruf Mandantengrenzen überschreiten darf. Am sichersten ist ein eigener, eng begrenzter Datensatz für Zugangsdaten pro Kunden-Host. Die zweitbeste Lösung verwendet einen kurzlebigen Token mit Audience- und Mandanten-Claims, die das Ziel prüft, sowie einer Client-Allowlist, in der weiterhin jeder zulässige Host genannt wird.
Ein globaler Token mit einer breiten Rolle ist beliebt, weil das Onboarding einfach wird. Mandanten hinzufügen, die Integration auf die Subdomain zeigen lassen und der Aufruf funktioniert. Dieselbe Bequemlichkeit ermöglicht es aber, dass ein Tippfehler, eine bösartige Konfigurationsänderung oder ein verwirrter Agent den Dienst eines anderen Kunden mit Zugangsdaten erreicht, die keine sinnvolle Zielbegrenzung haben.
Löse das nicht mit *.customers.example.com als genehmigtem Muster und der Annahme, jeder Treffer sei ein Kunde. Frage, wer diese Namen anlegen kann, wer DNS delegieren darf, welche Hosts zu Vorschauumgebungen routen und ob Namen nach der Kündigung eines Kunden bestehen bleiben. Eine Wildcard macht all diese Fragen zu Sicherheitsentscheidungen, meist ohne einen Prüfvermerk zu hinterlassen.
Es gibt Fälle, in denen eine kontrollierte Wildcard angemessen ist. Ein Anbieter kann mandantenbezogene Token ausstellen, die einen Mandanten-Identifier enthalten. Der Dienst lehnt Abweichungen ab, und ein internes Verzeichnis prüft den Mandanten-Host, bevor der Client sendet. In diesem Design ist die Wildcard nicht die Autorisierungsregel. Sie ist nur eine begrenzte Vereinfachung hinter einem maßgeblichen Mandantenverzeichnis. Wenn du dieses Verzeichnis und sein Fehlerverhalten nicht benennen und testen kannst, verwende exakte Einträge.
Private DNS erzeugt dasselbe Problem innerhalb eines Unternehmens. payments.prod.internal und payments.dev.internal sind möglicherweise keine öffentlichen Namen, aber unterschiedliche Ziele mit unterschiedlichen betrieblichen Kontrollen. Internes DNS ersetzt keine Begrenzung von Zugangsdaten.
Hostprüfungen müssen vor Discovery und nach der Normalisierung erfolgen
Service Discovery, benutzerdefiniertes Routing und Proxy-Konfigurationen können eine ansonsten sinnvolle Allowlist unbemerkt umgehen. Prüft der Code die ursprüngliche URL und ersetzt ein Resolver anschließend das interne Ziel, kann die Anwendung Zugangsdaten an eine andere Autorität senden. Umgekehrt kann eine Prüfung, die einen veränderbaren Host-Header verwendet, eine Anfrage genehmigen, deren Netzwerkverbindung woanders endet.
Verwende die Autorität der geparsten URL als Richtlinieneingabe. Stelle die TLS-Verbindung für diese Autorität her und prüfe das Zertifikat wie üblich. Deaktiviere die Zertifikatsprüfung nicht, um eine interne Route oder ein Test-Fixture zum Laufen zu bringen. Die Sicherheitshinweise von curl sagen ausdrücklich, dass ein Client, der die Gegenstelle nicht authentifizieren kann, nicht wissen kann, ob er den vorgesehenen Server erreicht hat.
Entscheide anschließend, was dein Vertrauensmodell über Proxys sagt. Ein Forward-Proxy ist eine Transportentscheidung und kein neues Ziel für Zugangsdaten, wenn der Client darüber eine TLS-Verbindung zum genehmigten Origin herstellt. Ein Reverse-Proxy, der TLS beendet, gehört zur Servicegrenze und muss genauso sorgfältig geprüft werden wie die API selbst. Ein HTTP-Proxy, der unverschlüsselte Authorization-Header erhält, hat Zugriff auf die Zugangsdaten. Nenne dieses Detail nicht einfach „Infrastruktur“.
Normalisiere internationalisierte Hostnamen über eine standardkonforme URL-Implementierung und vergleiche das kanonische Ergebnis. Lehne Userinfo in URLs wie https://[email protected]/ ab. Zugangsdaten in URLs gelangen in Protokolle, den Verlauf und Debugging-Ausgaben. Lehne Fragmente bei HTTP-Anfragen ab und entscheide ausdrücklich, ob Query-Strings vorab signierte Zugangsdaten enthalten dürfen. Eine allgemeine Bereinigungsfunktion kann kein Design retten, das jede URL akzeptiert und erst später versucht, schlechte URLs zu erkennen.
Die entscheidende Reihenfolge ist einfach: parsen, normalisieren, Ziel autorisieren, Zugangsschlüssel auswählen, Header erstellen, verbinden. Wenn eine spätere Operation die Autorität ändert, beginne wieder bei der Zielautorisierung.
Die Entscheidung protokollieren, nicht das Geheimnis
Ein Audit-Eintrag sollte belegen, welches Ziel der Client betrachtet und welche Regel für Zugangsdaten er ausgewählt hat, ohne das Geheimnis zu speichern. Du brauchst diesen Eintrag, wenn jemand wissen möchte, ob ein Token nach einer Deployment-Änderung einen benachbarten Host hätte erreichen können.
Speichere Felder wie Request-ID, Zeitpunkt, normalisierte Autorität, ID des Zugangsschlüsseldatensatzes, Autorisierungsergebnis, Quelle und Ziel einer Weiterleitung sowie einen Ergebnisc code. Hash oder maskiere Pfade, wenn sie Kundenkennungen enthalten. Protokolliere weder Authorization, benutzerdefinierte Schlüssel-Header, Query-Strings mit Signaturen noch vollständige Request-Bodies, nur weil sie beim Debugging hilfreich wären.
Ein guter Audit-Eintrag beantwortet eine konkrete Frage:
request_id=01J...
authority=https://api.billing.example.com:443
credential=billing-production
destination_check=allowed
redirect_count=0
result=201
Bei einer abgelehnten Anfrage an einen benachbarten Host sollte der Eintrag credential=none und destination_check=denied zeigen. Dieser Unterschied belegt, dass der Client die Anfrage ablehnte, bevor er ein Geheimnis auswählte. Wenn das Protokoll stattdessen einen Namen für die Zugangsdaten nennt und anschließend einen 403 vom falschen Host meldet, hat das System bereits mehr gesendet, als es sollte.
Sallyport hält das Geheimnis in seinem verschlüsselten Tresor und bewertet eine Aktion, bevor der Agent Zugangsdaten erhält. Das Aktivitätsjournal und das Sitzungsjournal geben Teams die Möglichkeit, den Aktionspfad zu prüfen und eine laufende Agentensitzung zu widerrufen, wenn eine hostgebundene Anfrage schiefgeht.
Beginne mit dem Verzeichnis. Schreibe für jeden Zugangsschlüssel eine vorgesehene Autorität auf und nenne anschließend einen benachbarten, einen Vanity- oder Migrationsnamen, einen regionalen und einen kundenspezifischen Namen, die ihn nicht erhalten dürfen. Wenn dein Client diese negativen Aussagen heute nicht treffen kann, besitzt er keine Grenze für Zugangsdaten. Er hat nur eine hoffnungsvolle Konvention.
FAQ
Funktionieren API-Schlüssel automatisch über Subdomains hinweg?
Nein. api.example.com und billing.example.com sind unterschiedliche Origins, auch wenn beide Namen vom selben Team betrieben werden. Behandle die Bindung eines Zugangsschlüssels als exakt, sofern der Aussteller nicht ausdrücklich eine größere Zielgruppe dokumentiert und du diesen Umfang getestet hast.
Ist es sicher, einen Bearer-Token an alle Subdomains zu senden?
Sie sollten den Token nur erhalten, wenn dein Client bewusst dafür konfiguriert wurde. Eine gemeinsame übergeordnete Domain belegt den Besitz eines Namensraums, nicht die Berechtigung, den Bearer-Token eines Dienstes wiederzuverwenden.
Kann eine HTTP-Weiterleitung einen API-Schlüssel an einen anderen Host weitergeben?
Eine Weiterleitung kann das Ziel nach der ersten Anfrage ändern. Deshalb braucht die Weiterleitung eine eigene Hostprüfung. Verlass dich nie darauf, dass ein HTTP-Client einen benutzerdefinierten Zugangsschlüssel-Header entfernt, nur weil er die integrierte HTTP-Authentifizierung entfernt.
Sollte jede Kunden-Subdomain einen eigenen Zugangsschlüssel verwenden?
Nein. Ein Host wie tenant-a.api.example.com sollte normalerweise einen eigenen, an den Mandanten gebundenen Zugangsschlüssel haben oder einen Token mit einem Mandanten-Claim, den der Dienst erzwingt. Ein allgemeiner Administratorschlüssel für Mandanten-Hosts macht aus einem Routingfehler einen mandantenübergreifenden Sicherheitsvorfall.
Brauchen regionale API-Endpoints eigene Zugangsschlüssel?
Ja, wenn der regionale Endpoint einen anderen Hostnamen hat. Dass zwei regionale Dienste zum selben Anbieter gehören, macht ihre Namen nicht austauschbar. Fehler bei der Region können Daten an die falsche Datenresidenz-Grenze senden, bevor die Authentifizierung überhaupt scheitert.
Sind Vanity-API-Domains für Produktionszugangsschlüssel sicher?
Vanity-Namen sind riskant, weil sie harmlos wirken und oft vor einer anderen Routing-, Protokollierungs- oder Besitzstruktur liegen. Binde Zugangsschlüssel an den kanonischen Service-Host, sofern der Anbieter den Vanity-Namen nicht ausdrücklich als gleichwertige authentifizierte Zielgruppe dokumentiert.
Wie teste ich, ob mein Client einen Token an benachbarte Domains sendet?
Protokolliere die genaue URL, den ausgewählten Zugangsschlüssel, das Weiterleitungsverhalten und ob die Anfrage einen Authentifizierungs-Header enthielt. Der aussagekräftigste Test ruft einen harmlosen Endpoint über genehmigte und bewusst nicht genehmigte Hosts auf und schlägt fehl, sobald der Zugangsschlüssel irgendwo auftaucht, wo er nicht hingehört.
Verhindert CORS, dass Zugangsdaten eine Subdomain erreichen?
CORS regelt, was JavaScript im Browser lesen darf. Cookies haben eigene Domain- und SameSite-Regeln. Ein serverseitiger Agent, eine CLI oder ein eigener HTTP-Client kann jeden Header an jeden Host senden, sofern der Code diese Anfrage nicht verhindert.
Sollte ich Wildcard-Host-Allowlists für API-Zugangsschlüssel verwenden?
Für Bearer-Token, benutzerdefinierte API-Key-Header und SSH-Ziele sind exakte Host-Allowlists normalerweise die richtige Wahl. Verwende eine enge Wildcard nur, wenn das Zugangsschlüsselsystem selbst die ausgewählte Mandanten- oder Service-Zielgruppe nachweist und du laufend prüfen kannst, welche konkreten Hosts darunterfallen.
Was ist die erste Maßnahme bei einem Fehler in der Zugangsschlüssel-Grenze?
Der erste Schritt ist eine Bestandsaufnahme aller Bindungen zwischen Zugangsschlüsseln und Hosts. Entferne anschließend breite Standardregeln wie *.example.com. Füge für jeden Zugangsschlüssel einen Negativtest hinzu: Ein genehmigtes Ziel muss ihn erhalten, während benachbarte, Vanity-, regionale und mandantenspezifische Ziele ihn nicht erhalten dürfen.