FlawOpen

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

● FlawOpen मैपिंग: CWE-601 · CVSS v4 8.6[1] · उच्च
सुरक्षा अनुसंधान · FlawOpen

Hermes Agent के नेटिव साइन-इन रीडायरेक्ट में पार्सिंग दोष

Tenable ने Hermes Agent के नेटिव साइन-इन में रीडायरेक्ट सत्यापन की गंभीर खामी प्रकाशित की। 0.21.6 से पुराने संस्करण प्रभावित हैं। 0.21.6 का सुधार Docker/Hermes Cloud और CLI/git इंस्टॉल के लिए आया; 11 अक्टूबर को जारी 0.21.7 में Desktop ऐप, Microsoft Store/MSIX, installer, Docker और Hermes Cloud भी सूचीबद्ध हैं। देखे गए रिलीज़ नोट्स में Termux का उल्लेख नहीं है; उस चैनल की अलग से जाँच करें। Tenable ने इसे High (CVSS 4.0 8.6) रेट किया है; कोई CVE निर्धारित नहीं है। CWE-601 रीडायरेक्ट के परिणाम के लिए संपादकीय वर्गीकरण है।[1], [2], [5]

💡 आसान भाषा में (ELI5)

मान लें कि स्वागत-कक्ष एक नक्शे से पता जाँचता है, मिले हुए पते को बिना बदले लिखता है और उसे दूसरे नक्शे वाले संदेशवाहक को देता है। संदेशवाहक ऐसी जगह जा सकता है जिसे स्वागत-कक्ष ने मंज़ूरी नहीं दी। Hermes ने Python parser से callback जाँचा, पर मूल स्ट्रिंग ब्राउज़र को दे दी, जो उसका अलग अर्थ निकाल सकता है।[1]

इस पेज के मुख्य शब्द

Native-app callback
डेस्कटॉप ऐप का अस्थायी स्थानीय वेब पता, जहाँ ब्राउज़र-आधारित साइन-इन का परिणाम लौटता है।[1], [4]
URL parser differential
दो URL parser एक ही इनपुट का अलग अर्थ निकालते हैं। एक अर्थ को जाँचकर दूसरे का उपयोग करना सुरक्षा सीमा तोड़ता है।[1], [3]
PKCE
Proof Key for Code Exchange प्राधिकरण कोड को उस ऐप के पास रखे गुप्त verifier से बाँधता है जिसने साइन-इन शुरू किया।[1], [4]
Loopback address
ऐसा IP पता जो उसी डिवाइस पर लौटे, जैसे 127.0.0.1 या ::1। Hermes का सुधार केवल मानक IP literal स्वीकार करता है, मनमाना दूरस्थ host नहीं।[3], [4]

फ्रेमवर्क मैपिंग

  • MITRE CWE के लिए FlawOpen की वैचारिक मैपिंग; किसी विक्रेता या CVE रिकॉर्ड ने इस शोध प्रदर्शन को यह कमजोरी ID नहीं दी है। CWE-601

हमले का चरण-दर-चरण प्रवाह

चरण 1

सार्वजनिक नेटिव-लॉगिन मार्ग callback प्राप्त करता है

उपयोगकर्ता के प्रमाणित होने से पहले authorization endpoint redirect URI और PKCE challenge लेता है।[1]

चरण 2

सर्वर और ब्राउज़र callback को अलग तरह से समझते हैं

कमज़ोर validator ने Python से parse हुआ hostname जाँचा, पर मूल स्ट्रिंग रखी। अस्पष्ट URL syntax ब्राउज़र को दूसरी authority पर भेज सकता है।[1], [3]

चरण 3

साइन-इन पूरा होने पर authorization code उजागर हो सकता है

पीड़ित के सामान्य login पूरा करने के बाद ब्राउज़र code को अपनी समझी हुई authority पर भेज सकता है। संबंधित PKCE challenge चुनने वाला हमलावर code बदलने की कोशिश कर सकता है। पीड़ित का login आवश्यक है; यह बिना interaction वाला account takeover नहीं है।[1]

चरण 4

URI मानकीकृत करें और उपलब्ध build अपडेट करें

सुधार अस्पष्ट syntax और गैर-मानक authority अस्वीकार करता है, canonical URI लौटाता है और उसी मान को सहेजता है। समर्थित चैनल से 0.21.7 या बाद में अपडेट करें; देखे गए रिलीज़ नोट्स में Termux का उल्लेख नहीं है, इसलिए उस चैनल की अलग से पुष्टि करें।[2], [5], [3]

सोर्स कोड: कमज़ोर बनाम सुरक्षित कार्यान्वयन

यह सुरक्षा सीमा का उदाहरण है, Hermes Agent का पूरा source code या exploit नहीं। कमजोर उदाहरण “parsed host जाँचें, raw input इस्तेमाल करें” वाला पैटर्न दिखाता है। सुरक्षित उदाहरण merged fix का गुण बताता है: अस्पष्ट इनपुट अस्वीकार करना, केवल canonical loopback authority स्वीकारना, canonical URI लौटाना और उसी मान को सहेजना/उपयोग करना। वास्तविक implementation और tests लिंक किए गए PR में हैं।[1], [3]

कमज़ोर कार्यान्वयन
from urllib.parse import urlparse

def validate_callback(raw):
    parsed = urlparse(raw)
    # मूल प्रवाह ने parse किए गए host की जाँच की, फिर भी raw URL को बनाए रखा।
    if parsed.scheme == "http" and parsed.hostname in {"127.0.0.1", "::1"}:
        return raw
    raise ValueError("callback must be loopback")
सुरक्षित और सुदृढ़ फ़िक्स
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 "/"))

इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट

स्रोत

← AI Security Directory →