Eigene Forschung
CVE-2026-114123: Fehlende Authentifizierung im D365 F&O MCP Server erklärt
CVE-2026-114123 ist eine fehlende Authentifizierung durch einen unsicheren Standardwert im Open-Source-Projekt D365 F&O MCP Server (npm-Paket d365fo-mcp): Die offizielle Azure-One-Click-Bereitstellung setzte den API-Schlüssel standardmäßig auf einen leeren Wert, und mit leerem Schlüssel ließ der Server jede Anfrage ohne Anmeldung durch. Wer der Anleitung folgte und das optionale Feld leer ließ, stellte damit einen öffentlich erreichbaren Endpunkt bereit, über den indexierter, proprietärer X++-Quellcode und Metadaten aus Dynamics 365 Finance & Operations abrufbar waren. Die Schwachstelle ist mit CVSS 7.5 (hoch) bewertet, betrifft alle Versionen bis einschließlich 1.10.1 und ist in Version 1.11.0 behoben; gemeldet hat sie CyberSec42.
- Das Azure-Template übergab einen leeren API-Schlüssel an den App Service, der Server wertete „leer“ als „Anmeldung aus“ und lauschte auf allen Netzwerkschnittstellen.
- Abrufbar waren die lesenden Werkzeuge, darunter Suche, Objektinformationen, Referenzen und Event-Handler, samt Ausschnitten des indexierten X++-Quellcodes. Schreibende Werkzeuge waren auf diesem Weg laut Advisory nicht erreichbar.
- Bewertung laut Advisory und CVE-Eintrag: CVSS 3.1 Basiswert 7.5, Vektor
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N, Klassen CWE-306 und CWE-1188. - Was Betreiber tun sollten: auf 1.11.0 oder neuer aktualisieren, vorher einen starken
API_KEYsetzen, und den Endpunkt zusätzlich auf Netzwerkebene abschirmen.
Hintergrund
Was der Server tut und was in seinem Index liegt.
Zum AbschnittDie Schwachstelle
Mechanik in einfachen Worten und technisch.
Zum AbschnittWer betroffen war
Versionen und Bereitstellungswege.
Zum AbschnittBehebung
Was der Fix ändert und was Betreiber tun sollten.
Zum AbschnittZeitleiste
Nur öffentlich belegte Daten.
Zum AbschnittDas Muster dahinter
Optionale Anmeldung als unsicherer Standard.
Zum AbschnittDie Fakten auf einen Blick
| Merkmal | Angabe |
|---|---|
| Kennung | CVE-2026-114123, GHSA-8764-fh3m-wf7g |
| Produkt | D365 F&O MCP Server (dynamics365ninja/d365fo-mcp-server), npm-Paket d365fo-mcp |
| Klasse | CWE-306 „Missing Authentication for Critical Function“, CWE-1188 „Insecure Default Initialization of Resource“ |
| Schwere | CVSS 3.1: 7.5, hoch (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N) |
| Betroffen | alle Versionen bis einschließlich 1.10.1 |
| Behoben | 1.11.0, veröffentlicht am 13.08.2026 |
| Veröffentlicht | GitHub-Advisory am 12.08.2026, CVE-Eintrag am 21.10.2026 (GitHub als CVE Numbering Authority) |
| Credit | Gemeldet von CyberSec42 (GitHub: lwebmedia), als Reporter in der GitHub-Advisory |
Hintergrund: Was der D365 F&O MCP Server ist
Das Model Context Protocol (MCP) ist ein offener Standard, über den KI-Assistenten Werkzeuge und Datenquellen ansprechen. Ein MCP-Server nimmt die Werkzeugaufrufe eines KI-Clients entgegen und beantwortet sie aus einem Zielsystem. Der D365 F&O MCP Server ist laut CVE-Eintrag ein MCP-Server, um X++-Code und Metadaten von Dynamics 365 Finance & Operations abzufragen. Entwickler nutzen ihn, damit ein KI-Assistent beim Schreiben von X++ auf die echten Klassen, Tabellen, Felder und Labels des eigenen Systems zurückgreifen kann.
Dafür baut der Server einen Index, eine Symboldatenbank aus dem PackagesLocalDirectory der D365-Umgebung. Die Sicherheitsrichtlinie des Projekts beschreibt den Inhalt deutlich: X++-Quellcode-Ausschnitte, die Verknüpfung von Erweiterungen und Event-Handlern, Sicherheitsrollen, Privilegien und Duties sowie Label-Texte, ausdrücklich einschließlich der eigenen, kundenspezifischen Modelle. Dieser Index ist also das Geschäftsgeheimnis des jeweiligen Unternehmens in maschinenlesbarer Form.
Der Server kennt zwei Betriebsarten, im MCP-Jargon Transporte. Bei stdio startet der KI-Client den Server als lokalen Prozess, es gibt keinen Netzwerkendpunkt. Beim HTTP-Transport läuft der Server als Netzwerkdienst und nimmt JSON-RPC-Anfragen unter /mcp an. Für den HTTP-Betrieb bietet das Projekt im README einen Knopf „Deploy to Azure“ an, der einen Azure App Service samt Konfiguration aus einem ARM-/Bicep-Template anlegt. Um diesen Weg geht es hier. Grundsätzliches zur Absicherung von MCP-Servern steht in unserem Leitfaden zu MCP-Servern.
Die Schwachstelle
In einfachen Worten
Stellen Sie sich ein Archiv vor, dessen Tür ein Zahlenschloss hat. Bei der Lieferung ist das Schloss so eingestellt, dass eine leere Kombination die Tür öffnet, und im Aufbauplan steht neben dem Feld für die Kombination „optional“. Wer das Archiv nach Plan aufstellt und das Feld überspringt, hat eine Tür, die für jeden aufgeht, der davorsteht. Und das Archiv steht an einer öffentlichen Straße.
So verhielt sich die Azure-Bereitstellung des D365 F&O MCP Servers bis Version 1.10.1. Die Kombination ist der API-Schlüssel, die Straße ist die öffentliche Adresse des Azure App Service.
Technisch
Drei Stellen wirkten zusammen, alle in der Advisory mit Datei und Zeile belegt:
- Das Template. In
infrastructure/azuredeploy.jsonundinfrastructure/main.bicepwar der ParameterapiKeymit dem Standardwert""deklariert und wurde unverändert in die App-Service-EinstellungAPI_KEYübernommen. Der Bereitstellungsassistent im Azure-Portal ließ sich deshalb abschließen, ohne das Feld je auszufüllen. - Die Middleware.
src/middleware/apiKeyAuth.tsbehandelte einen leeren oder fehlendenAPI_KEYals „Authentifizierung deaktiviert“ und reichte jede Anfrage durch. Die Middleware sitzt global vor allen Routen und war bei leerem Schlüssel damit auch für/mcpwirkungslos. - Die Bindung.
src/index.tsband den HTTP-Listener an0.0.0.0, wennHOSTnicht gesetzt war. Das Template legte weder Private Endpoint noch VNet-Integration, IP-Beschränkung oder App-Service-Authentifizierung an.
Das Template setzte auf dem App Service außerdem fest MCP_SERVER_MODE=read-only. Damit waren die schreibenden Werkzeuge auf diesem Weg nicht angeboten. Die lesenden blieben erreichbar, darunter search, get_object_info, batch_get_info, extension_info, security_info, find_references und find_event_handlers. Mehrere davon geben das Feld source_snippet aus dem Index zurück, also Ausschnitte des X++-Quellcodes. Die Sicherheitsrichtlinie des Projekts ordnet MCP_SERVER_MODE inzwischen ausdrücklich als Aufteilung der Werkzeugoberfläche ein, nicht als Berechtigungsgrenze: Der Modus begrenzt, welche Werkzeuge erreichbar sind, nicht wer sie erreichen darf.
Zur Einordnung des Vektors: AV:N, PR:N und UI:N bedeuten Angriff über das Netz, ohne Anmeldung und ohne Handlung eines Nutzers. C:H steht für einen hohen Verlust an Vertraulichkeit. Integrität und Verfügbarkeit sind laut Vektor nicht betroffen, weil auf diesem Weg keine schreibenden Werkzeuge angeboten wurden. Wir haben den Basiswert von 7.5 anhand der Formel der CVSS-3.1-Spezifikation nachgerechnet.
Schematischer Ablauf
- Ein Unternehmen stellt den Server über „Deploy to Azure“ bereit und lässt das als optional beschriebene Feld
apiKeyleer. - Der App Service läuft mit
API_KEY=""unter ihrer öffentlichen HTTPS-Adresse. - Ein Aufrufer, der diese Adresse kennt, sendet eine JSON-RPC-Anfrage an
/mcp, ohne Schlüssel-Header. - Die Middleware erkennt keinen konfigurierten Schlüssel und reicht die Anfrage an das Werkzeug weiter.
- Das Werkzeug antwortet wie für einen berechtigten Nutzer, einschließlich der Quellcode-Ausschnitte aus dem Index.
Wir veröffentlichen bewusst keinen Exploit-Code. Die Beschreibung reicht, um die eigene Installation einzuordnen und den Fix nachzuvollziehen.
So haben wir geprüft
Der Fund stammt aus einer reinen Quellcode-Prüfung des öffentlichen Repositorys. Wie in der Advisory festgehalten, haben wir keine laufende Installation dieser Software, kein Azure-Abonnement einer anderen Partei und keine D365-Finance-&-Operations-Umgebung angesprochen, gescannt oder kontaktiert. Code aus dem Projekt haben wir zu keinem Zeitpunkt ausgeführt, gebaut oder installiert. Der Ablauf oben ist am Quellcode nachvollzogen, nicht an einem fremden System.
Wer betroffen war
Die GitHub-Advisory nennt das npm-Paket d365fo-mcp in allen Versionen bis einschließlich 1.10.1, der CVE-Eintrag formuliert es als „vor 1.11.0“. Beschrieben ist dort der Weg über die offizielle Azure-One-Click-Bereitstellung. Der CVE-Eintrag grenzt ausdrücklich ab: Installationen, die durch einen gesetzten API-Schlüssel, eine wirksame vorgelagerte Authentifizierung oder Netzwerkbeschränkungen geschützt sind, fallen nicht unter dieses Szenario.
| Bereitstellung | Einordnung bis 1.10.1 |
|---|---|
stdio (lokaler Prozess des KI-Clients) | Kein HTTP-Endpunkt, der beschriebene Weg besteht nicht |
Azure One-Click, apiKey leer, keine eigene Netzwerk- oder Zugriffskontrolle | Betroffen. Lesende Werkzeuge ohne Anmeldung über die öffentliche Adresse erreichbar |
Azure One-Click mit gesetztem apiKey | Anfragen ohne gültigen Schlüssel werden abgewiesen |
| Eigene Netzwerkbeschränkung oder vorgelagerte Authentifizierung (Private Endpoint, IP-Beschränkung, Easy Auth) | Laut CVE-Eintrag außerhalb des Szenarios, sofern ein Angreifer den Endpunkt dadurch nicht erreicht |
Zwei Ergänzungen stammen aus den Commit-Nachrichten des Maintainers. Erstens war nach seiner Analyse auch eine Bereitstellung über die mitgelieferte Azure-DevOps-Pipeline auf einen von Hand angelegten App Service ohne API_KEY genauso offen. Der zweite Fix-Commit schließt diesen Weg mit. Zweitens hält er fest, dass der Hostname nicht schwer zu finden ist: Er leitet sich aus dem Namen der Ressourcengruppe ab und taucht in Certificate-Transparency-Protokollen auf.
Wie groß das Risiko im Einzelfall war, hängt davon ab, ob der Schlüssel leer blieb, ob eine eigene Azure-Absicherung vorgeschaltet war und welche Modelle im Index lagen.
Behebung und was Betreiber jetzt tun sollten
Was der Fix in 1.11.0 ändert
Die Korrektur besteht aus zwei Commits, die mit Version 1.11.0 erschienen sind:
- Schlüssel ist Pflicht.
apiKeyist im Template jetzt ein Pflichtparameter mit mindestens 32 Zeichen. Der Assistent im Azure-Portal lässt sich ohne Schlüssel nicht mehr abschließen. - Sichere Bindung ohne Schlüssel. Ohne
API_KEYbindet der Server standardmäßig nur noch an127.0.0.1statt an alle Schnittstellen. Ein vergessener Schlüssel kostet damit Erreichbarkeit, nicht Vertraulichkeit. - Start wird verweigert. Soll der Server auf einer öffentlichen Schnittstelle lauschen und nichts authentifiziert ihn, startet er nicht. Für Installationen mit vorgelagerter Authentifizierung gibt es den dokumentierten Schalter
ALLOW_UNAUTHENTICATED=true. - Klarheit in Doku und Tests. Die Startmeldung nennt den Status der Authentifizierung, die Doku beschreibt den Read-only-Modus jetzt als Werkzeugauswahl und nicht als Zugriffsschutz, eine
SECURITY.mdist hinzugekommen, und neue Tests prüfen Middleware und Template.
Der Fix ist als Breaking Change gekennzeichnet: Ein bestehender App Service ohne API_KEY startet nach dem Update nicht mehr. Das ist gewollt, denn aus einer stillen Offenlegung wird ein sichtbarer Fehler.
Empfehlungen für Betreiber
Die folgenden Schritte sind unsere Empfehlungen. Wo sie sich auf Hinweise des Projekts stützen, ist das vermerkt.
| Schritt | Maßnahme |
|---|---|
| 1. Schlüssel setzen | Vor dem Update einen zufälligen, langen API_KEY im App Service hinterlegen, etwa mit openssl rand -hex 32, wie es die Projektdoku vorschlägt. Sonst startet 1.11.0 nicht. |
| 2. Aktualisieren | Auf 1.11.0 oder neuer aktualisieren. Version 1.10.1 ist laut Advisory noch betroffen. |
| 3. Einordnen | War der Schlüssel leer und der App Service ohne eigene Netzwerkbeschränkung erreichbar, sollten Sie davon ausgehen, dass der Index von außen lesbar war, und das intern entsprechend bewerten. |
| 4. Protokolle sichten | Falls HTTP-Protokolle des App Service aktiviert waren: nach Anfragen an /mcp von unbekannten Adressen suchen. |
| 5. Netzwerk abschirmen | Private Endpoint oder IP-Beschränkung vor den App Service setzen, wenn die Adressen des Teams bekannt sind. Das empfiehlt auch die Sicherheitsrichtlinie des Projekts. |
| 6. Identität statt Einzelschlüssel | Easy Auth mit Entra ID vorschalten, damit jeder Nutzer eigene Zugangsdaten hat. Den gemeinsamen Schlüssel erneuern, wenn jemand das Projekt verlässt (ebenfalls laut Projekt-Richtlinie). |
Zeitleiste
Aufgeführt sind nur Daten, die sich aus öffentlichen Quellen belegen lassen.
| Datum | Ereignis | Beleg |
|---|---|---|
| 27.07.2026 | Version 1.5.2 erscheint, der in der Advisory geprüfte Stand | npm-Registry, Advisory |
| 28.07.2026 | Advisory im Repository angelegt | GitHub-Advisory (API) |
| 29.07.2026 | Erster Fix-Commit verfasst | GitHub, Commit e70bd05 |
| 11.08.2026 | Version 1.10.1 erscheint, die letzte betroffene Version | GitHub-Release, npm-Registry |
| 12.08.2026 | Beide Fix-Commits im Hauptzweig, GitHub-Advisory GHSA-8764-fh3m-wf7g veröffentlicht | GitHub |
| 13.08.2026 | Version 1.11.0 mit dem Fix erscheint | GitHub-Release, npm-Registry |
| 20.10.2026 | CVE-Nummer durch GitHub als CNA reserviert | CVE-Eintrag |
| 21.10.2026 | CVE-Eintrag CVE-2026-114123 veröffentlicht | CVE.org, NVD |
Das Muster dahinter: optionale Anmeldung als Standard
Hinter CVE-2026-114123 steht ein Muster, das bei Werkzeugen für Entwickler häufig vorkommt. Lokal ist ein Server ohne Anmeldung bequem, also ist die Anmeldung optional. Sobald derselbe Code über ein Template in die Cloud geht, wird aus „optional“ ein offener Dienst im Internet. Gefährlich wird es, wenn ein leeres Geheimnis als „Prüfung aus“ gilt und das Bereitstellungswerkzeug genau diesen leeren Wert als Standard mitbringt.
In unserer Erläuterung der OWASP MCP Top 10 berührt der Fall zwei Klassen: fehlende Transport-Authentifizierung aus Klasse 1 und unsichere Standardwerte aus Klasse 9. Für Entwickler von MCP-Servern lassen sich daraus vier Regeln ableiten:
- Leeres Geheimnis heißt verweigern. Fehlt der Schlüssel, lehnt der Server ab oder startet nicht, statt durchzulassen.
- Templates erzwingen, was die Doku empfiehlt. Ein sicherheitsrelevanter Parameter im Infrastruktur-Template hat keinen leeren Standardwert, sondern ist Pflicht oder wird zufällig erzeugt.
- Lokal binden, solange nichts authentifiziert. Ohne Anmeldung lauscht der Server nur auf
127.0.0.1. Der Fix in 1.11.0 setzt genau das um. - Betriebsmodus ist keine Zugriffskontrolle. Ein Read-only-Modus begrenzt, was erreichbar ist, nicht wer. Bei vertraulichen Daten ist schon das Lesen der Schaden.
Für Betreiber gilt die Kehrseite: Ein MCP-Server mit HTTP-Transport ist ein Netzwerkdienst mit Zugriff auf Ihre Daten. Er verdient dieselbe Behandlung wie jede andere API, also Authentifizierung, Netzwerkbeschränkung und einen Blick darauf, was ein One-Click-Template tatsächlich anlegt.
Dank an den Maintainer
Wir danken dem Maintainer des Projekts (GitHub: dynamics365ninja) für die koordinierte Zusammenarbeit. Die Meldung lief vertraulich über eine GitHub-Repository-Advisory. Der Maintainer hat die Ursache an mehreren Stellen behoben, statt nur den Standardwert zu ändern, dabei einen weiteren Bereitstellungsweg mit abgedeckt, Tests ergänzt, eine Sicherheitsrichtlinie veröffentlicht, die CVE-Nummer bei GitHub als CNA angefordert und CyberSec42 in der Advisory als Reporter genannt.
Ist Ihr MCP-Server so abgeschirmt, wie Sie denken?
Wir prüfen MCP-Server und KI-Agenten im schriftlich vereinbarten Umfang: wer den Endpunkt erreichen kann, was ohne Anmeldung durchgeht, was Ihre Bereitstellungs-Templates tatsächlich anlegen und welche Daten ein Werkzeugaufruf zurückgibt. Jeder Befund kommt mit einem nachvollziehbaren Nachweis und einem konkreten Korrekturvorschlag. Mehr dazu unter KI-Pentest & MCP-Sicherheit.
KI-Pentest anfragenCyberSec42 ist eine unabhängige technische Sicherheitsprüfung, keine akkreditierte Zertifizierungsstelle und keine Rechtsberatung. CyberSec42 steht in keiner Verbindung zum Projekt D365 F&O MCP Server oder zu Microsoft. Dynamics 365 ist eine Marke von Microsoft.
Häufige Fragen
Was ist CVE-2026-114123?
Eine fehlende Authentifizierung durch einen unsicheren Standardwert im D365 F&O MCP Server. Die offizielle Azure-One-Click-Bereitstellung setzte den API-Schlüssel standardmäßig leer, und mit leerem Schlüssel ließ der Server Anfragen ohne Anmeldung zu. Der CVE-Eintrag bewertet sie mit CVSS 7.5 (hoch).
Welche Versionen sind betroffen?
Laut GitHub-Advisory alle Versionen des npm-Pakets d365fo-mcp bis einschließlich 1.10.1. Behoben ist die Schwachstelle in 1.11.0 vom 13.08.2026. Setzen Sie vor dem Update einen API_KEY, sonst startet die neue Version auf dem App Service nicht.
Bin ich betroffen, wenn ich den Server lokal über stdio nutze?
Im stdio-Modus startet der KI-Client den Server als lokalen Prozess ohne HTTP-Endpunkt, der beschriebene Weg besteht dort nicht. Beschrieben ist die Schwachstelle für die Azure-Bereitstellung mit HTTP-Transport. Aktualisieren sollten Sie trotzdem.
Ist Dynamics 365 Finance & Operations selbst betroffen?
Nein. Der CVE-Eintrag nennt ausschließlich den D365 F&O MCP Server. Betroffen waren die Daten, die der Server aus Ihrer D365-Umgebung indexiert hat, nicht die D365-Umgebung selbst. Die Sicherheitsrichtlinie des Projekts nimmt Schwachstellen in D365 F&O ausdrücklich aus.
Wurde die Schwachstelle aktiv ausgenutzt?
Die öffentlichen Quellen, also Advisory, CVE-Eintrag und Fix-Commits, treffen dazu keine Aussage. Ob Ihre eigene Installation betroffen war, lässt sich nur anhand Ihrer Konfiguration und gegebenenfalls Ihrer Protokolle einordnen.
Weiterlesen
- Forschung: unsere öffentlich dokumentierten Funde
- Die OWASP MCP Top 10, praktisch erklärt
- MCP-Server absichern: der praktische Leitfaden
- Leistung: KI-Pentest & MCP-Sicherheit
Quellen
- GitHub-Advisory: GHSA-8764-fh3m-wf7g
- CVE.org: CVE-2026-114123
- NVD: CVE-2026-114123
- GitHub: Fix-Commit e70bd05
- GitHub: Fix-Commit 384394a
- GitHub: Release v1.11.0
- GitHub: Änderungen zwischen v1.10.1 und v1.11.0
- GitHub: Sicherheitsrichtlinie des Projekts (SECURITY.md)
- npm: d365fo-mcp
- MITRE: CWE-306
- MITRE: CWE-1188
- FIRST: CVSS v3.1 Specification