Trust No Origin: CORS Mirage in Azure Ingress

Hinweis: Dieser Artikel beschreibt eine Schwachstelle, die zum Zeitpunkt der Veröffentlichung noch aktiv ausnutzbar ist. Reproduktion der betroffenen Konfiguration sowie die Verifikation der Schwachstelle wurden gemeinsam mit einem blacklens.io Partner durchgeführt.
Die Schwachstelle wurde im Rahmen eines Responsible Disclosure Prozesses zunächst an Microsoft (MSRC) gemeldet und vor der Veröffentlichung ausreichend Zeit zur Analyse eingeräumt.
Alles begann mit einem routinemäßigen Pentest. Nachdem zahlreiche andere Angriffsvektoren bereits untersucht & ausgeschlossen wurden, rückte ein bestimmter Teil der Infrastruktur in den Fokus. Was zunächst unscheinbar wirkte, führte letztendlich zur Entdeckung einer Schwachstelle – ohne verfügbaren Fix, in einem Produkt, das weiterhin ein weit verbreiteter Infrastruktur Baustein des Internets ist und in unzähligen Unternehmen genutzt wird. Möglicherweise noch für Jahre.
Doch was ist CORS – und warum ist es wichtig?
CORS (Cross-Origin Resource Sharing) ist ein Sicherheitsmechanismus, der Webservern dabei hilft, auf Basis der Herkunft einer Anfrage (dem sogenannten Origin-Header) den Zugriff auf bestimmte Ressourcen zu erlauben oder verweigern. Diese Ressourcen können unter anderem auch sensible Daten wie Tokens oder andere Secrets umfassen.
Das Risiko einer CORS-Schwachstelle hängt stark von der jeweiligen Implementierung und Architektur ab. Besonders gefährlich wird es, wenn CORS-Fehlkonfigurationen mit anderen Schwachstellen kombiniert werden – ein Umstand, der häufig unterschätzt wird.
Ein grundlegendes Prinzip sollte daher immer gelten: Sicherheit muss von Grund auf mitgedacht werden. Es ist generell keine gute Praxis, sich blind auf einzelne Sicherheitsmechanismen zu verlassen.
In einer idealen Welt könnte dieser Artikel an dieser Stelle enden. Leider ist das nicht der Fall.
Schwachstelle im Überblick
Das Verhalten entsteht durch die Art, wie das Azure Application Routing Add-on für Azure Kubernetes Service (AKS) für den zugrunde liegenden ingress-nginx Controller konfiguriert bzw. verwendet wird. Unter bestimmten Bedingungen ermöglicht sie eine Umgehung der CORS-Origin-Prüfung. Ursache ist die fehlerhafte Validierung von Origin-Header durch den verwalteten NGINX Ingress Controller. Welche zum Glück von modernen Browser richtig gehandhabt wird & dadurch in Schwere um einiges reduziert wird.
Azure Application Routing
Azure Application Routing stellt einen verwalteten NGINX Ingress Controller für AKS bereit. Wird dort CORS über die standardmäßigen Ingress-Annotations aktiviert, überprüft der Controller eingehende Origin-Header, um zu entscheiden, welche Quellen Zugriff erhalten.
Das Problem entsteht, wenn die Reihenfolge der gesetzten Origin stimmt & mehrere Werte enthält/mehrfach gesetzt wird. Dann validiert in solchen Fällen der Ingress nicht korrekt, sondern reflektiert bösartige Origin auch in der Antwort.
Zuerst das korrekte Verhalten - Beispielsweise kann ein Angreifer eine Anfrage mit folgendem Header senden:

Der kritische Teil:
Wie erwähnt beeinflusst die Reihenfolge der Origin das Verhalten. Wird zuerst ein legitimer Origin-Wert übermittelt, wird die Anfrage korrekterweise abgelehnt. Wird jedoch zuerst der bösartige Origin gesetzt und danach ein erlaubter, akzeptiert der Ingress den gesamten Header.

Dies funktioniert auch alternativ mit zwei getrennt gesetzten Header. Ingress akzeptiert die inkorrekte CORS Anfrage und antwortet in beiden Fällen mit der geschützen Resource - im Beispiel einem Secret.
Damit entsteht eine CORS-Antwort, welche mehrere Origins enthält & nicht der W3C-Spezifikation entspricht (also nicht “Internet” konform).
Dieses Verhalten deutet auf eine inkonsistente Validierungslogik im verwalteten Ingress hin.
Reale Auswirkung
Wir haben das folgende falsche Verhalten:
- Mehrere Origin werden reflektiert, auch eingeschleuste
- Eine eingebettete vertraute Origin reicht App Routing die ganze Liste zu akzeptieren
- Authentifiziertes CORS ist möglich (falls aktiv)
- System unterbindet Zugriff nicht (korrekterweise in umgekehrter Reihenfolge)
Somit handelt es sich nun um einen Fehler in der serverseitigen Validierung.
Während moderne Browser solche Antworten meist blockieren, kann die Schwachstelle in serverseitigen Trust-Modellen, Microservice Architekturen oder z.B. API-Gateways zu schwerwiegenden Sicherheitsproblemen führen, wenn nicht in einem weiteren Layer CORS erneut kontrolliert wird oder zusätzliche Sicherheitsmaßnahmen rechtzeitig eingreifen.
Aus bekannten CORS Fällen ergeben sich dann in Praxis Schwachstellen wie:
- Umgehen von Origin basierten Authentifizierungen
- Umgehen von Cross-Tenant oder Cross-Application Vertrauensstellungen
- Unautorisierter API Zugriff
- Token Diebstahl in OAuth/OIDC internen Login Flows
- Erweiterung von Berechtigungen in Mikroservice Architekturen
- Falsche Weiterleitung/Umgehung von Richtlinien in API-Gateways und Service-Meshes
- Falsche Vertrauensannahmen innerhalb von Unternehmensinfrastrukturen
Etc.
Als konkretes Azure Beispiel, wenn die Rolle von CORS unterschätzt wird, werden Schwachstellen wie „EmojiDeploy” ermöglicht, wo zu einem Azure-Webdienst-RCE führte mit 30.000$ Bounty:
https://www.tenable.com/blog/Emoji-Deploy-Smile-Your-Azure-web-service-just-got-Rced

Was betroffene Unternehmen tun können
Da der zugrunde liegende Ingress-NGINX-Stack voraussichtlich ab März 2026 langsam das Ende seiner Lebensdauer erreicht & Azure-Support aktuell nur noch bis 30 November 2026 vorgesehen ist, sollten betroffene Unternehmen frühzeitig prüfen, ob eine Migration auf einen alternativen, nicht betroffenen Ingress-Stack bzw. der Gateway API sinnvoll ist.
https://www.kubernetes.dev/blog/2025/11/12/ingress-nginx-retirement/
https://azure.microsoft.com/en-us/updates?id=555839
Ein dauerhafter Weiterbetrieb bestehender Deployments ohne Anpassungen kann langfristig erhebliche Risiken bergen.
In der Praxis bleiben jedoch leider viele Kubernetes-Cluster über Jahre hinweg auf älteren Komponenten versions-pinned, wodurch Implementierungsschwachstellen auch lange nach dem offiziellen Support Ende bestehen bleiben & zu versteckten Risiken werden.
Unabhängig von dieser konkreten Schwachstelle gilt jedoch eine grundsätzliche Sicherheitsregel:
Ein einzelner Sicherheitsmechanismus sollte niemals als alleinige Schutzmaßnahme dienen.
Gerade Mechanismen wie CORS werden in der Praxis häufig überschätzt oder falsch eingesetzt. In komplexen Cloud- und Microservice-Architekturen sollten daher immer mehrere Sicherheitsebenen kombiniert werden, beispielsweise:
- zusätzliche serverseitige Validierung von Origin und Access-Control-Allow-Origin
- konsequente Authentifizierung und Autorisierung unabhängig von HTTP-Headern
- zusätzliche Sicherheitskontrollen auf Ebene von API-Gateways oder Service-Meshes
Ob eine eigene Infrastruktur oder ein eingesetzter Drittanbieter von solchen Implementierungsfehlern betroffen ist, lässt sich häufig erst durch gezielte Pentests oder Sicherheitsanalysen zuverlässig feststellen.
Genau hier setzt blacklens.io an:
Mit kontinuierlichem 24/7-Scanning und optionalem Pentesting-as-a-Service hilft die Plattform dabei, Schwachstellen in interner, externer und Cloud-Infrastruktur frühzeitig zu erkennen und reale Angriffspfade sichtbar zu machen.
Egal ob Active Directory Fehlkonfigurationen, welche laterale Bewegungen im Netzwerk ermöglichen oder Schwachstellen in zb. Kubernetes- /API-Infrastrukturen – blacklens.io schafft Überblick Ihrer gesamte Angriffsoberfläche und hilft Ihnen dabei, die kritischsten Risiken zuerst priorisieren zu können.
„Wir setzen in unseren Software-Lösungen konsequent auf Zero-Trust und etablierte DevSecOps Methoden – auch wenn dieses Finding bei unseren Kundenlösungen für keine kritische Sicherheitslücke gesorgt hat, zeigt es uns, dass trotz größter Sorgfalt, immer wieder externe Faktoren Angriffsfläche bieten können und regelmäßige manuelle Penetration-Tests zur Vermeidung blinder Flecken wichtig sind.“
– Mario te Best, WareTec IT Solutions GmbH
Technische Details
Betroffene Produkt/e
- Azure Kubernetes Service (AKS)
- Azure App Routing Add-on
- Managed NGINX Ingress Controller
- Ingress class: webapprouting.kubernetes.azure.com
- Standard Konfiguration erstellt via:
Erstellung Cluster
az aks create `
--resource-group $ResourceGroupName `
--name $ClusterName `
--location $Location `
--enable-app-routing `
--generate-ssh-keys
Kubernetes minimal Konfiguration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cors
annotations:
# Enable CORS
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, PATCH, OPTIONS"
nginx.ingress.kubernetes.io/cors-allow-origin: "http://trusted-example.com, http://127.0.0.1"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization"
nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range"
nginx.ingress.kubernetes.io/cors-max-age: "1728000"
# Use custom response
nginx.ingress.kubernetes.io/configuration-snippet: |
default_type image/svg+xml;
return 200 "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"200\" height=\"200\"><rect width=\"200\" height=\"200\" fill=\"blue\"/><text x=\"50%\" y=\"50%\" text-anchor=\"middle\" fill=\"white\" font-size=\"20\">CORS Test</text></svg>";
spec:
ingressClassName: webapprouting.kubernetes.azure.com
rules:
- http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: does-not-exist
port:
number: 3000
Beispiel Anfrage
Origin: https://attacker.com, http://trusted-example.com
Oder
Origin: https://attacker.com
Origin: http://trusted-example.com
Ingress Antwort
Access-Control-Allow-Origin: https://attacker.com, http://trusted-example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers: DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization
Access-Control-Expose-Headers: Content-Length,Content-Range
Access-Control-Max-Age: 1728000
Timeline
02.Dezember 2025 – Erstellung Report bei MSRC
03.Dezember - Vergabe MSRC Case Nummer VULN-167454 -> Status wechsel„Review/Repro“
19.Januar - Anfrage triage/status Update
21.Januar - Korrespondenz mit Bekanntgabe Techniker sind noch am nachstellen -> mit Bitte um Informationen zur geplanten Veröffentlichung
28.Januar - Bekanntgabe des laufenden Entwurfs
02.Februar - Bestätigung & Weitergabe der Informationen an Techniker
05.März - Fertigstellung Artikel & Bekanntgabe MSRC
09.März - offizielle öffentliche Bekanntgabe
Referenzen:
https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties
https://hackerone.com/reports/430249
https://medium.com/@LogicalHunter/identity-aware-proxy-misconfiguration-google-cloud-vulnerability-813d2a07a4ed
https://medium.com/@umesh-sharma/from-discovery-to-exploit-a-beginners-guide-to-cors-bugs-a3cf2bde6c5d
Fazit & Ausblick
Der Fall zeigt exemplarisch, wie selbst kleine Implementierungsdetails in weit verbreiteten Infrastrukturkomponenten zu sicherheitsrelevanten Problemen führen können.
Mit dem absehbaren End-of-Life des Ingress-NGINX Controllers werden viele bestehende Deployments weiterhin in Betrieb bleiben, obwohl ihre technische Basis nicht mehr aktiv weiterentwickelt wird.
Dadurch können sich Schwachstellen in weltweit eingesetzten Ingress-Stacks über Jahre hinweg in Produktionsumgebungen existieren – und warten nur darauf in Pentests oder von einem Angreifer entdeckt zu werden….
Gerade in modernen Cloud-Architekturen gilt eine einfache Regel:
Trust no Origin.





