FlawOpen

flawopen.com/AI Security/hermes-agent-native-signin-redirect-parser-confusion

● FlawOpen-Zuordnung: CWE-601 · CVSS v4 8.6[1] · Hoch
Sicherheitsforschung · FlawOpen

Fehler bei der nativen Anmeldeumleitung in Hermes Agent

Tenable meldete einen schwerwiegenden Fehler bei der Prüfung von Weiterleitungen in der nativen Hermes-Agent-Anmeldung. Versionen vor 0.21.6 sind betroffen. Die Korrektur aus 0.21.6 erschien für Docker/Hermes Cloud und CLI-/Git-Installationen; Version 0.21.7 vom 11. Oktober nennt zusätzlich die Desktop-App, Microsoft Store/MSIX, den Installer, Docker und Hermes Cloud. Termux wird in den geprüften Versionshinweisen nicht genannt; prüfen Sie diesen Kanal separat. Tenable stuft den Fehler als High (CVSS 4.0 8.6) ein; eine CVE wurde nicht vergeben. CWE-601 ist eine redaktionelle Zuordnung zur Weiterleitungsfolge.[1], [2], [5]

💡 Einfache Erklärung (ELI5)

Stellen Sie sich einen Empfang vor, der eine Adresse auf einer Karte prüft, den unveränderten Text notiert und ihn einem Kurier mit einer anderen Karte gibt. Der Kurier könnte an einem nicht freigegebenen Ort landen. Hermes prüfte den Callback mit dem Python-Parser, gab danach aber den Rohwert an den Browser weiter, der ihn anders interpretieren kann.[1]

Kernkonzepte & Begriffe

Native-app callback
Eine vorübergehende lokale Webadresse, über die eine Desktop-App das Ergebnis einer browsergestützten Anmeldung empfängt.[1], [4]
URL parser differential
Zwei URL-Parser deuten dieselbe Eingabe unterschiedlich; eine Interpretation zu prüfen und später eine andere zu verwenden verletzt die Sicherheitsgrenze.[1], [3]
PKCE
Proof Key for Code Exchange bindet einen Autorisierungscode an einen geheimen Prüfer, den die App behält, die die Anmeldung gestartet hat.[1], [4]
Loopback address
Eine IP-Adresse, die zum selben Gerät zurückführt, etwa 127.0.0.1 oder ::1. Die Korrektur erlaubt kanonische IP-Literale, keine beliebigen entfernten Hosts.[3], [4]

Framework-Zuordnungen

  • Konzeptionelle Zuordnung von FlawOpen zu MITRE CWE; weder ein Anbieter noch ein CVE-Datensatz hat diese Schwachstellen-ID dieser Forschungsdemonstration zugewiesen. CWE-601

Schritt-für-Schritt Angriffsablauf

Schritt 1

Eine öffentliche Native-Login-Route nimmt einen Callback entgegen

Der Autorisierungsendpunkt erhält vor der Anmeldung eine Redirect-URI und eine PKCE-Challenge.[1]

Schritt 2

Server und Browser deuten den Callback unterschiedlich

Der anfällige Validator prüfte den von Python geparsten Hostnamen, behielt jedoch die ursprüngliche Zeichenfolge. Mehrdeutige URL-Syntax kann den Browser zu einer anderen Authority führen.[1], [3]

Schritt 3

Nach einer Anmeldung kann der Autorisierungscode offengelegt werden

Nach der normalen Anmeldung des Opfers kann der Browser den Code an die von ihm erkannte Authority senden. Ein Angreifer mit der passenden PKCE-Challenge kann versuchen, ihn einzulösen. Die Anmeldung des Opfers ist erforderlich; es handelt sich nicht um eine Übernahme ohne Interaktion.[1]

Schritt 4

Kanonisieren und den ausgelieferten Build aktualisieren

Die Korrektur verwirft mehrdeutige Syntax und nichtkanonische Authorities, gibt die kanonische URI zurück und speichert diesen Wert. Aktualisieren Sie über einen unterstützten Kanal auf 0.21.7 oder neuer; prüfen Sie Termux separat, da es in den geprüften Versionshinweisen zu 0.21.7 nicht genannt wird.[2], [5], [3]

Quellcode: Verwundbar vs. Sicher

Dies ist ein veranschaulichendes Grenzmodell, nicht der vollständige Hermes-Agent-Quelltext und kein Exploit. Das anfällige Beispiel fasst das Muster geparsten Host prüfen/Rohwert verwenden zusammen. Das gehärtete Beispiel zeigt die Eigenschaft des gemergten Fixes: mehrdeutige Eingaben ablehnen, nur kanonische Loopback-Authorities erlauben, die kanonische URI zurückgeben und genau diesen Wert speichern/verwenden. Das verknüpfte PR enthält Implementierung und Tests.[1], [3]

VERWUNDBARE IMPLEMENTIERUNG
from urllib.parse import urlparse

def validate_callback(raw):
    parsed = urlparse(raw)
    # Der ursprüngliche Ablauf prüfte den geparsten Host, verwendete danach aber weiterhin die Roh-URL.
    if parsed.scheme == "http" and parsed.hostname in {"127.0.0.1", "::1"}:
        return raw
    raise ValueError("callback must be loopback")
GEHÄRTETER SICHERHEITS-PATCH
from urllib.parse import urlparse, urlunparse

LOOPBACK_HOSTS = {"127.0.0.1": "127.0.0.1", "::1": "[::1]"}

def validate_callback(raw):
    if not raw.isascii() or "\\" in raw or any(ord(c) <= 0x20 or ord(c) == 0x7f for c in raw):
        raise ValueError("callback must use canonical loopback syntax")
    try:
        parsed = urlparse(raw)
        host, port = parsed.hostname, parsed.port
    except ValueError as exc:
        raise ValueError("invalid callback") from exc
    if parsed.scheme != "http" or "#" in raw or parsed.username is not None or parsed.password is not None:
        raise ValueError("callback must be a plain loopback URL")
    authority_host = LOOPBACK_HOSTS.get(host)
    if authority_host is None:
        raise ValueError("callback host must be a loopback IP literal")
    authority = authority_host + (f":{port}" if port is not None else "")
    if parsed.netloc != authority:
        raise ValueError("callback authority is not canonical")
    return urlunparse(parsed._replace(path=parsed.path or "/"))

Checkliste für Engineering & Systemsicherheit

Quellen

← AI Security Directory →