FlawOpen

flawopen.com/Teardowns/cve-2026-90970-gitlab-ai-gateway-prompt-template-sandbox-escape

● CVE-2026-90970 · CVSS 9.9[4] · Kritisch
Sicherheitsforschung · FlawOpen

CVE-2026-90970: Prompt-Sandbox-Ausbruch im GitLab AI Gateway

Ein speziell gestalteter Duo-Agent-Platform-Flow konnte aus der Prompt-Template-Sandbox des AI Gateway ausbrechen und Befehle ausführen. Betreiber eines selbst gehosteten Gateways sollten auf die korrigierte Version ihres GitLab-Zweigs aktualisieren.[1], [4]

CVSS-VektorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H[4]
💡 Einfache Erklärung (ELI5)

Stellen Sie sich eine Person vor, die aus Gesprächsprotokollen einen Bericht erstellt. Sie soll freigegebene Felder als einfachen Text übernehmen. Ein präpariertes Template konnte sie jedoch dazu bringen, die Funktion „Wiederherstellen“ des Ablageordners aufzurufen. Dadurch baute die Anwendung aus gespeicherten Daten aktive Objekte, statt nur Wörter zu kopieren. So wurde die Grenze zwischen dem Anzeigen von Daten und ihrer Interpretation durch die Anwendung überschritten. Der Bericht des Forschers beschreibt den konkreten Weg über parse_raw() und pickle; GitLabs Hinweis bestätigt den Sandbox-Ausbruch und die Befehlsausführung, aber nicht alle Einzelschritte.[3], [6]

Kernkonzepte & Begriffe

AI Gateway
GitLab-Dienst, der KI-Funktionen mit Modellanbietern verbindet; das selbst gehostete Gateway-Image hat eine eigene Version.[5], [1]
Prompt template
Vorlage, die feste Anweisungen mit Laufzeitwerten wie Flow-Eingaben und Gesprächskontext verbindet.[3], [6]
Sandbox escape
Nutzung eines Verhaltens in einer eingeschränkten Umgebung, um deren vorgesehene Grenze zu überschreiten.[3], [6]
CWE-1336
Unzureichende Neutralisierung spezieller Elemente einer Template-Engine; der CVE-Datensatz ordnet diese Schwäche zu.[4], [1]

Framework-Zuordnungen

  • CWE-Referenz für die in diesem Leitfaden beschriebene Schwachstelle: CWE-1336

Ursachenanalyse

GitLab bestätigt, dass ein authentifizierter Benutzer mit Zugriff auf Duo Agent Platform unter bestimmten Bedingungen eine spezielle Flow-Konfiguration nutzen konnte, um die Prompt-Template-Sandbox zu umgehen und beliebige Befehle auf dem AI Gateway auszuführen. Das Problem ist CWE-1336, CVSS 9,9. Der Hinweis nennt nicht alle Bedingungen oder die genaue verwundbare Funktion. Ein öffentlicher Commit vom 17.09.2026 ergänzt PromptSandboxedEnvironment, das Methodenaufrufe auf gebundenen Objekten laut Beschreibung verhindert, und härtet Jinja-Operationen und -Filter. Das passt zur Beschränkung von Template-Aktionen auf Laufzeitobjekten, doch der Commit nennt dieses CVE nicht und öffentliche Quellen verbinden ihn nicht mit den korrigierten Images. Als separate öffentliche Härtungsänderung darstellen; keine öffentliche Quelle verbindet sie mit diesem CVE oder den korrigierten Images. Das öffentliche GitLab-Arbeitselement Nr. 1850 beschreibt einen genaueren Pfad: Ein Jinja-Template ruft parse_raw() auf einem HumanMessage von LangChain aus dem Gesprächsverlauf auf und löst dadurch die Pickle-Deserialisierung aus. Das Arbeitselement ordnet diese Demonstration dem Bericht des Forschers zu und sagt, sie habe in der GitLab-Staging-Umgebung stattgefunden; der Herstellerhinweis nennt nicht alle betroffenen Bedingungen.[1], [3], [4], [2]

Korrigierte Releases des selbst gehosteten AI Gateway

Bereitstellung / Release-ZweigKorrigiertes AI-Gateway-ReleaseMaßnahme
Selbst gehostetes GitLab, Zweig 19.219.2.4Auf den passenden selbst gehosteten Gateway-Image-Tag aktualisieren und das bereitgestellte Image prüfen.
Selbst gehostetes GitLab, Zweig 19.319.3.2Auf den passenden selbst gehosteten Gateway-Image-Tag aktualisieren und das bereitgestellte Image prüfen.
Selbst gehostetes GitLab, Zweig 19.419.4.1Auf den passenden selbst gehosteten Gateway-Image-Tag aktualisieren und das bereitgestellte Image prüfen.
Von GitLab gehostetes AI GatewayLaut GitLab bereits behoben.Prüfen, ob das Deployment das von GitLab gehostete Gateway nutzt; die Hinweise zu selbst gehosteten Images gelten hier nicht.

Schritt-für-Schritt Angriffsablauf

Schritt 1

Ein Benutzer kann einen eigenen Flow konfigurieren

Der Hinweis nennt einen authentifizierten Benutzer mit Duo-Agent-Platform-Zugriff. Eine genauere Rolle oder alle nötigen Flow-Funktionen werden nicht genannt.[1], [3]

Schritt 2

Der Flow liefert eine spezielle Template-Konfiguration

Eine spezielle Flow-Konfiguration erreicht die Prompt-Template-Sandbox. Der öffentliche Hinweis enthält weder eine vollständige sichere Reproduktion noch den genauen Ausdruck.[1], [3]

Schritt 3

Die Template-Ausführung überschreitet die Sandbox-Grenze

Das öffentliche GitLab-Arbeitselement Nr. 1850 berichtet, dass ein Template parse_raw() auf einem HumanMessage von LangChain aus dem Gesprächsverlauf aufrufen und dadurch die Pickle-Deserialisierung auslösen konnte. Dies ist der vom Forscher dokumentierte Pfad; leite daraus weder alle betroffenen Flows noch den Herstellerpatch ab.[3]

Schritt 4

Befehle können auf dem Gateway ausgeführt werden

Bestätigt ist die Ausführung beliebiger Befehle auf dem AI Gateway, also serverseitige Ausführung und nicht nur ein Fehler beim Befolgen von Modellanweisungen.[1], [3]

Quellcode: Verwundbar vs. Sicher

GitLab-Arbeitselement 1850 berichtet, dass der verwundbare Flow ein HumanMessage-Objekt von LangChain an Jinja weitergab, wo ein Template parse_raw() aufrufen und die Pickle-Deserialisierung auslösen konnte. Dieses defensive Beispiel hält Nachrichtenobjekte aus dem Template-Kontext heraus, übergibt nur Text und verweigert den Zugriff auf aufrufbare Attribute und Methoden. Es veranschaulicht die zu schließende Grenze, ist aber nicht der von GitLab veröffentlichte Patch. Der öffentliche Commit 89b72644 ist eine separate Sicherheitsänderung: Sein Titel betrifft Jinja-Block-Set-Schreibvorgänge; keine öffentliche Quelle verbindet ihn mit CVE-2026-90970 oder den korrigierten Images. Betreiber sollten die vom Hersteller genannten behobenen Versionen installieren.[3], [2], [6]

Quelltextauszug: ai_gateway/prompts/base.py (gemeldeter verwundbarer Formatter; illustrative Härtung)

VERWUNDBARE IMPLEMENTIERUNG
# Auszug aus dem verwundbaren Pfad, beschrieben in GitLab-Arbeitspunkt 1850.
from jinja2 import PackageLoader
from jinja2.sandbox import SandboxedEnvironment
from langchain_core.prompts.string import DEFAULT_FORMATTER_MAPPING
from typing import Any

jinja_loader = PackageLoader("ai_gateway.prompts", "definitions")
jinja_env = SandboxedEnvironment(loader=jinja_loader)

def jinja2_formatter(template: str, /, **kwargs: Any) -> str:
    return jinja_env.from_string(template).render(**kwargs)

DEFAULT_FORMATTER_MAPPING["jinja2"] = jinja2_formatter
GEHÄRTETER SICHERHEITS-PATCH
# Beispiel für ein Schutzmuster; dies ist kein GitLab-Patch für diese CVE.
from typing import Any
from jinja2 import StrictUndefined
from jinja2.sandbox import ImmutableSandboxedEnvironment

class DataOnlyPromptEnvironment(ImmutableSandboxedEnvironment):
    def is_safe_attribute(self, obj: Any, attr: str, value: Any) -> bool:
        if callable(value):
            return False
        return super().is_safe_attribute(obj, attr, value)

    def is_safe_callable(self, obj: Any) -> bool:
        return False

def render_prompt(template: str, history: list[Any]) -> str:
    safe_history = []
    for message in history:
        content = message.content
        if not isinstance(content, str):
            raise TypeError("prompt history must contain text only")
        safe_history.append({"content": content})

    env = DataOnlyPromptEnvironment(undefined=StrictUndefined)
    return env.from_string(template).render(history=safe_history)

Checkliste für Engineering & Systemsicherheit

Quellen