Phase 13: Tools & Protocols

एमसीपी सुरक्षाः विषाक्त मेटाडेटा, रूटिंग और एमआरटीआर स्टेट

बिना नागरिकता का मतलब विश्वासहीन नहीं है, इसका मतलब है कि प्रत्येक अनुरोध से सर्वर और गेटवे को कॉल को स्वतंत्र रूप से मान्य करने के लिए आवश्यक साक्ष्य उजागर होते हैं।

Type: Learn

Languages: Python

Prerequisites: Phase 13 · 07 (MCP server), Phase 13 · 08 (MCP client)

Time: ~60 minutes

सीखने के लक्ष्य

  • उपकरण विवरण, टिप्पणी, क्लाइंट जानकारी और सर्वर जानकारी को अविश्वसनीय डेटा के रूप में व्यवहार करें।
  • मेटाडेटा विषाक्तता, वर्णक परिवर्तन, और क्रॉस-सर्वर नाम टकराव का पता लगाएं।
  • 2026-07-28 अनुरोध मेटाडेटा और स्ट्रीम करने योग्य HTTP रूटिंग हेडर को मान्य करें।
  • एमआरटीआर की रक्षा करें requestStateछेड़छाड़ के विरुद्ध और सटीक तर्क के लिए पुष्टि को बाध्य करें।
  • एक प्रमुख पर प्राधिकरण और दर सीमाएं लागू करें, न कि एक हटाए गए प्रोटोकॉल सत्र।

समस्या

एक मॉडल यह तय करने के लिए उपकरण विवरण पढ़ता है कि क्या कॉल करना है। एक राउटर यह तय करने के लिए उपकरण नाम पढ़ता है कि अनुरोध कहां भेजा जाए। एक उपयोगकर्ता यह तय करने के लिए लेबल पढ़ता है कि क्या मंजूरी देनी है। एक दुर्भावनापूर्ण वर्णक तीनों को निशाना बना सकता है।

आधिकारिक एमसीपी सुरक्षा मार्गदर्शन प्रत्यक्ष हैः विवरण और टिप्पणी को अविश्वसनीय माना जाना चाहिए जब तक कि वे विश्वसनीय सर्वर से न आए। तब भी, तैनाती का विश्वास बदल सकता है। सर्वर अपडेट, समझौता किया गया पैकेज, रजिस्ट्री त्रुटि या गेटवे विलय मॉडल को जो देखता है उसे बदल सकता है।

वर्तमान प्रोटोकॉल सुरक्षा सीमा को भी बदलता है। 2026-07-28 में कोई कोर हैंडशैक नहीं है और कोई परिवहन सत्र नहीं है। एक सुरक्षा डिजाइन जो केवल अनुमोदन, दर सीमाओं या ऑडिट इतिहास द्वारा कुंजी देता है।Mcp-Session-Idयह एक वर्तमान डिजाइन नहीं है।

अवधारणा

सात हमले की सतहों की जांच करने लायक

सावधानी बरतने के लिए अस्पष्ट निर्देशों के बजाय एक ठोस सूची का उपयोग करें।

  1. Metadata poisoning.एक विवरण में घोषित उपकरण व्यवहार से संबंधित नहीं निर्देश हैं।
  2. Descriptor rug pull.पहले से अनुमोदित नाम, विवरण, योजना या टिप्पणी परिवर्तन।
  3. Cross-server shadowing.दो बैकेंड एक ही अयोग्य उपकरण नाम का खुलासा करते हैं और रूटिंग चुपचाप एक का चयन करता है।
  4. Header and body confusion. Mcp-Methodया Mcp-NameJSON-RPC अनुरोध से असहमत है।
  5. Capability escalation.एक साथी एक विस्तार या क्लाइंट सुविधा का दावा करता है और सर्वर उस घोषणा को प्राधिकरण के लिए गलत करता है।
  6. MRTR state tampering.एक ग्राहक बदलता है requestState, एक अलग प्रश्न का उत्तर देता है, या विभिन्न तर्कों के साथ पुष्टि का पुनः उपयोग करता है।
  7. Supply-chain identity confusion.एक परिचित प्रदर्शन नाम प्रकाशक या सर्वर की पहचान का प्रमाण के रूप में माना जाता है।

इन सतहों पर ओवरलैप होता है. हैश पिनिंग वर्णक परिवर्तनों में मदद करता है लेकिन यह साबित नहीं करता है कि पहला वर्णक सुरक्षित था। स्थैतिक स्कैनिंग स्पष्ट वाक्यांशों को पकड़ता है लेकिन सूक्ष्म निर्देश नहीं। नामस्थान एक टकराव वर्ग को रोकता है लेकिन एक दुर्भावनापूर्ण नामस्थान सर्वर नहीं है। नियंत्रण को ढेर करें।

वर्तमान अनुरोध कूपन प्रमाण है, पहचान नहीं

प्रत्येक 2026-07-28 अनुरोध में निम्नलिखित शामिल हैंः

json{
  "_meta": {
    "io.modelcontextprotocol/protocolVersion": "2026-07-28",
    "io.modelcontextprotocol/clientCapabilities": {
      "elicitation": {"form": {}}
    },
    "io.modelcontextprotocol/clientInfo": {
      "name": "security-lab",
      "version": "1.0.0"
    }
  }
}

प्रत्येक अनुरोध पर संस्करण और क्षमता आकार को मान्य करें। संगत प्रतिक्रिया आकार चुनने के लिए क्षमताओं का उपयोग करें। उपयोग न करें clientInfoयह स्व-रिपोर्ट किया गया है।

वही चेतावनी io.modelcontextprotocol/serverInfoयह लॉग और डिबगिंग के लिए उपयोगी है. यह प्रमाण पत्र, रजिस्ट्री प्रमाणन या प्राधिकरण निर्णय नहीं है.

नीति से पहले रूटिंग को मान्य करें

के लिएtools/call, स्ट्रीम करने योग्य HTTP में शामिल हैंः

textMCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: notes.export

हेडर विधि को बॉडी विधि के बराबर होना चाहिए। हेडर नाम के बराबर होना चाहिए params.name. मतभेदों को अस्वीकार करें-32020बैक-एंड चुनने, आरबीएसी लागू करने या दर-सीमा टोकन का उपभोग करने से पहले।

इस क्रम से एक आम अस्पष्टता समाप्त होती हैः एक घटक शरीर को अधिकृत करता है जबकि दूसरा हेडर द्वारा मार्ग देता है।

वायर वैलिडेशन एक सटीक अनुक्रम का अनुसरण करता है। JSON-RPC और मेटाडेटा प्रकारों को मान्य करें, हेडर मानों को शरीर के साथ तुलना करें, फिर जांचें कि क्या मिलान संस्करण समर्थित है। एक असंगत हेडर HTTP 400 को वापस करता है -32020. यदि हेडर और बॉडी असमर्थित संस्करण पर सहमत हैं, तो HTTP 400 को के साथ लौटाएं-32022और dataठीक है{"supported":["2026-07-28"],"requested":"<actual>"}. एक अज्ञात विधि HTTP 404 को वापस करती है -32601. .

प्रत्येक त्रुटि वस्तु वैकल्पिक शामिल है dataजब अनुबंध को संरचित पुनर्प्राप्ति जानकारी की आवश्यकता होती है।idएक स्वीकार किए गए HTTP सूचना रिक्त शरीर के साथ 202 लौटता है।

पूरी वर्णक को पिन करें

एक विवरण हैश अकेले स्कीमा और टिप्पणी परिवर्तनों को याद करता है। उपयोगकर्ता द्वारा अनुमोदित वर्णनात्मक क्षेत्रों को कैनोनिकलाइज़ और हैश करेंः

pythonnormalized = json.dumps(tool, sort_keys=True, separators=(",", ":"))
digest = hashlib.sha256(normalized.encode()).hexdigest()

डिजेस्ट को एक योग्य कुंजी के नीचे रखें जैसे notes.export, साथ ही प्रकाशक सबूत और इस खिलौना उदाहरण के बाहर अनुमोदन समय के साथ।

हर ताज़ा पेय परः

  • अज्ञात कुंजीः समीक्षा तक संगरोध।
  • एक ही कुंजी, अलग पाचनः क्वारंटीन के रूप में एक कार्पेट खींचने के लिए जब तक पुनः अनुमोदित.
  • दोहरी अयोग्य नामः निर्धारक नामस्थान की आवश्यकता होती है।
  • स्कैनर हिटः ब्लॉक और पूर्ण वर्णक की समीक्षा करें।

हश समानता स्थिरता साबित करती है, सुरक्षा नहीं। एक जहरीले वर्णक जब पूरी तरह से चिपकाया जाता है तो जहरीला रहता है।

स्थैतिक स्कैनिंग एक त्रिभुज तार है

सरल पैटर्न भूमिका टैग, निर्देश ओवरराइड, छिपाने, गुप्त पहुंच और अंधेरे नेटवर्क गंतव्यों को चिह्नित कर सकते हैं। वे स्थापना समय और आईसी के लिए काफी सस्ते हैं।

वे अर्थिक प्रमाण नहीं हैं। एक सुरक्षित विवरण में वैध चेतावनी में एक चिह्नित वाक्यांश हो सकता है। एक दुर्भावनापूर्ण विवरण हर वाक्यांश से बच सकता है। स्कैनर आउटपुट को समीक्षा प्रमाण के रूप में माना जाए, न कि स्वचालित निर्दोषता स्कोर।

विलय से पहले नाम स्थान

मान लीजिए दो सर्वर दोनों को उजागर करते हैं searchकभी भी खोज आदेश को यह तय नहीं करने दें कि कौन जीतता है।

textnotes.search
issues.search

योग्य नाम सार्वजनिक गेटवे का नाम है। बैक-एंड मैपिंग को अलग से रिकॉर्ड करें। स्थिर नाम अनुमोदन, ऑडिट, हैश पिन्स और Mcp-Nameरूटिंग एक ही वस्तु को संदर्भित करता है।

क्षमताएँ संगतता घोषणाएँ हैं

अनुरोध परclientCapabilitiesसर्वर को बताता है कि क्लाइंट किस प्रोटोकॉल को संसाधित कर सकता है। यह क्लाइंट को टूल, डेटा या कार्यों तक पहुंच प्रदान नहीं करता है।

प्राधिकरण अभी भी सत्यापित मूल और संसाधन नीति से आता है। अनुक्रम हैः

  1. परिवहन क्रेडेंशियल्स की पुष्टि करें।
  2. संस्करण, हेडर और अनुरोध आकार को मान्य करें।
  3. क्षमता संगतता की जाँच करें।
  4. मूल, उपकरण, संसाधन और तर्क को अधिकृत करें।
  5. उपयोगकर्ता इनपुट निष्पादित करें या अनुरोध करें।

राज्य रहित एमआरटीआर पुष्टि की रक्षा करें

एक परिणामी उपकरण को उपयोगकर्ता की पुष्टि की आवश्यकता हो सकती है। वर्तमान एमसीपी सर्वर-से-क्लाइंट कॉलबैक के बजाय मल्टी राउंड-ट्रिप अनुरोधों का उपयोग करता है।

पहला उत्तरः

json{
  "resultType": "input_required",
  "inputRequests": {
    "confirm": {
      "method": "elicitation/create",
      "params": {
        "mode": "form",
        "message": "Export notes to archive?",
        "requestedSchema": {
          "type": "object",
          "properties": {
            "confirm": {"type": "boolean"}
          },
          "required": ["confirm"]
        }
      }
    }
  },
  "requestState": "opaque-integrity-protected-value"
}

क्लाइंट इनपुट प्राप्त करता है और एक नई JSON-RPC आईडी के साथ मूल विधि को पुनः प्रयास करता हैः

json{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "notes.export",
    "arguments": {"query": "private", "destination": "archive"},
    "requestState": "opaque-integrity-protected-value",
    "inputResponses": {
      "confirm": {
        "action": "accept",
        "content": {"confirm": true}
      }
    },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {
        "elicitation": {"form": {}}
      }
    }
  }
}

प्रत्येक inputRequestsमान एक पूर्ण एम्बेडेड अनुरोध है methodऔर params. इसकी कुंजी को संबंधित प्रविष्टि से मेल लेना चाहिए inputResponses. एक फॉर्म उत्प्रेरणा वस्तु-मूल का उपयोग करता है requestedSchema, और क्लाइंट ने सर्वर द्वारा अनुरोध करने से पहले फॉर्म इलिकिटेशन क्षमता घोषित कर दी होगी।

वर्तमान क्षमता में दो मान्य फॉर्म घोषणाएं हैं। {"elicitation":{}}स्पष्ट रूप से रूप उत्प्रेरणा का समर्थन करता है, जबकि {"elicitation":{"form":{}}}केवल URL-केवल घोषणा जैसे {"elicitation":{"url":{}}}सर्वर HTTP 400 को वापस करता है -32021और data.requiredCapabilitiesबराबर {"elicitation":{"form":{}}}. .

उपचारrequestStateपाठ कोड में HMAC और सटीक तर्क मिलान का उपयोग करके सीमा को दृश्यमान बनाया जाता है।

गैर-गैटवेज लेजर को एक गेटवे ऑब्जेक्ट के अंदर नहीं रहना चाहिए। रननेबल मॉडल एक सीमित, टीटीएल-कट्टा रीप्ले स्टोर इंजेक्ट करता है जिसे कई गेटवे इंस्टेंस द्वारा साझा किया जा सकता है। इसका परमाणु दावा निष्पादन सीमा हैः केवल एक सत्यापित स्वीकृति या स्पष्ट टर्मिनल गिरावट राज्य का उपभोग करती है। एक गलत प्रतिक्रिया या cancelउत्पादन बेड़े को साझा टिकाऊ भंडारण में समान शर्त का दावा करना चाहिए।

प्रोटोकॉल सत्र में छिपे हुए पुष्टि संदर्भ को संग्रहीत न करें. किसी भी सर्वर इंस्टेंस को पुनः प्रयास को मान्य करने में सक्षम होना चाहिए।

उच्च जोखिम वाले कॉल के लिए नियम दो

तीन अक्षों के साथ एक कॉल को वर्गीकृत करेंः

  • यह अविश्वसनीय इनपुट का उपभोग करता है।
  • यह संवेदनशील डेटा तक पहुँच सकता है।
  • इससे बाहरी कार्रवाई होती है।

एक स्वचालित चरण में तीनों को जोड़ना नहीं चाहिए। इसे विभाजित करें, विशेषाधिकार को कम करें, या MRTR के माध्यम से स्पष्ट उपयोगकर्ता इनपुट का अनुरोध करें। यह एक डिजाइन हेउरिस्टिक है, प्रोटोकॉल क्षमता नहीं।

निष्पादन से पहले अधिकार को कम करना

अकेले देशहीनता सुरक्षा नहीं है। यह छिपे हुए प्रोटोकॉल इतिहास को हटा देता है, लेकिन एक आत्मनिर्भर अनुरोध अभी भी एक अधिकृत हैंडलर से डेटा लीक करने या अपरिवर्तनीय परिवर्तन करने के लिए कह सकता है। सुरक्षा प्रत्येक सीमा पर प्राधिकरण को कम करने से आती हैः

  1. Typed verb.एक सीमित ऑपरेशन का वर्णन करें जैसे archive_note, एक सामान्य नहीं runया requestएक उपकरण जो असंबद्ध शक्तियों को व्यक्त कर सकता है।
  2. Validated arguments.एक बंद योजना का उपयोग करें जहां व्यावहारिक, अज्ञात क्षेत्रों को अस्वीकार करें, पहचानकर्ताओं को एक बार सामान्य बनाएं, कैप आकार, और नीति मूल्यांकन से पहले गंतव्य, किरायेदार और संसाधन स्वामित्व को मान्य करें।
  3. Current authorization.प्रमाणित मूल को सटीक क्रिया, संसाधन, वातावरण और सामान्यीकृत तर्कों से जोड़ें। उपकरण टिप्पणी और क्लाइंट क्षमताएं इस अधिकार को प्रदान नहीं करती हैं।
  4. Action-bound approval.एक परिणामात्मक कॉल के लिए, टाइप किए गए क्रिया और सामान्यीकृत तर्कों के एक डाइजेस्ट के साथ अनुमोदन को जोड़ें, साथ ही मूल, समाप्ति और एक बार नीति। किसी भी बदलते क्षेत्र के लिए एक नया निर्णय आवश्यक है।
  5. First-class refusal.मॉडल अस्वीकार, समाप्त अनुमोदन, उपयोगकर्ता की गिरावट, और असुरक्षित गंतव्य सामान्य परिणामों के रूप में जो कोई दुष्प्रभाव नहीं करते हैं। अस्वीकार को कमजोर वापसी उपकरण में अनुवाद न करें।
  6. Redacted audit evidence.रिकॉर्ड करें कि किसने पूछा, किसने स्वीकार किया वर्णक और नीति संस्करण का उपयोग किया गया, किस सामान्य लक्ष्य को अधिकृत किया गया था, निर्णय ने अनुमति दी या अस्वीकार कर दी, और निष्पादन शुरू हुआ या नहीं। गुप्त के बजाय डिजेस्ट या संपादित मूल्यों को स्टोर करें।

प्रत्येक चरण अगले घटक के लिए क्या कर सकता है, यह संकुचित करता है। अंतिम हैंडल को पहले से ही मान्य डोमेन कमांड प्राप्त करना चाहिए, कच्चे मॉडल पाठ के साथ व्यापक क्रेडेंशियल नहीं। एक MRTR पुनः प्रयास, कार्य अद्यतन या गेटवे-फॉरवर्ड कॉल पर पूरी श्रृंखला को दोहराएं। एक प्रारंभिक स्वीकृति बाद के अनुरोधों को विश्वसनीय सत्र यातायात में नहीं बदलती है।

वर्तमान और विरासत में मिले बातचीत मार्ग

नए 2026-07-28 कार्यान्वयनों के लिए रूट, सैम्पलिंग और लॉगिंग अप्रचलित हैं। एक गेटवे केवल एक संस्करण-गेटेड संगतता पथ के रूप में पुराने अनुरोध-चैनल कोड को बनाए रख सकता है।

प्रति सत्र नमूने लेने के सीमांक के आसपास एक नया बचाव न बनाएं। प्रमाणीकृत मूल, जारीकर्ता, संसाधन, उपकरण और समय विंडो पर कोटा लागू करें। वर्तमान इंटरैक्टिव काम के लिए, एमआरटीआर इनपुट अनुरोधों और प्रतिक्रियाओं का निरीक्षण करें।

बिना नागरिकता वाले परिवहन जाँच

  • एकल POST एंडपॉइंट पर आधुनिक MCP संदेश स्वीकार करें।
  • आधुनिक GET और DELETE के लिए 405 लौटाएं।
  • न तो मूंछें और न ही निर्भरता Mcp-Session-Id. .
  • विरासत सत्र को अनदेखा करें और प्राधिकरण इनपुट के रूप में शीर्षकों को पुनः खेलें।
  • उस पोस्ट के लिए JSON या अनुरोध-स्कोप SSE लौटाएं।
  • उपयोग करेंsubscriptions/listenकेवल दीर्घकालिक परिवर्तन सूचनाओं के लिए।

इसे बनाओ

code/main.pyयह एक छोटी सी प्रक्रिया में सुरक्षा गेटवे मॉडल लागू करता है। यह पूर्ण उपकरण वर्णकों को कैनोनिकलाइज और पिन करता है, मेटाडेटा विषाक्तता और छायांकन की रिपोर्ट करता है, आधुनिक अनुरोध कूपन और रूटिंग मानों को मान्य करता है, और हस्ताक्षरित के साथ दो-राउंड पुष्टि निर्यात करता है requestStateऔर एक इंजेक्शन साझा पुनरावृत्ति स्टोर.

मॉडल एक HTTP एडाप्टर JSON शरीर और रूटिंग हेडर को पार्स करने के बाद शुरू होता है। यह मान्य नहीं करता है Content-Typeया Accept. उसी डिस्पैचर को पाठ 09 के पूर्ण स्ट्रीम करने योग्य HTTP एडाप्टर से कनेक्ट करें, जिसके लिए आवश्यकता होती है Content-Type: application/jsonऔर एक Acceptदोनों को युक्त मूल्य application/jsonऔर text/event-stream. .

इसे चलाओः

bashcd phases/13-tools-and-protocols/15-mcp-security-tool-poisoning
python3 code/main.py
python3 -m unittest discover code/tests -v

नमूना जानबूझकर एक वर्णक को उत्परिवर्तन करता है। स्कैनर और पाचन तुलना स्वतंत्र निष्कर्ष उत्पन्न करती है। निर्यात तब प्रदर्शित करता है कि input_requiredप्रतिक्रिया और राज्यहीन पुनः प्रयास।

इसका प्रयोग करें

प्रतिस्थापनSAFE_TOOLSअपने स्वीकृत सर्वर से एक सामान्य स्नैपशॉट के साथ। क्रेडिट और रहस्य स्नैपशॉट से बाहर रखें। अपने पाचन अद्यतन करने से पहले हर नए या बदल वर्णक की समीक्षा करें।

एक गेटवे पर, खोज के दौरान और फिर से भेजने से पहले एक ही जांच करें। एक कैश खोज कार्य को कम कर सकता है, लेकिन कैश किए गए अनुमोदन की समाप्ति या अवैध होना चाहिए जब वर्णक बदलता है।

इसे भेजें

यह सबक जहाजों outputs/skill-mcp-threat-model.md. यह मेटाडेटा, रूटिंग, क्षमता, प्राधिकरण, एमआरटीआर, कैशिंग, रजिस्ट्री और संगतता सीमाओं पर एक वर्तमान प्रोटोकॉल खतरे मॉडल का उत्पादन करता है।

व्यायाम

  1. प्रमाणित मूल और वर्तमान प्राधिकरण निर्णय को सील एमआरटीआर राज्य से जोड़ें, फिर किसी अन्य मूल के तहत पुनः प्रयास को अस्वीकार करें।
  2. इन-मेमोरी रिप्ले स्टोर को एक स्थायी सशर्त सम्मिलन से बदलें और दो प्रक्रियाओं को एक नॉनस का दावा नहीं कर सकते हैं।
  3. पुनः प्रक्षेपण के बाद एक विफलता का इंजेक्शन दें लेकिन एक अनुकरणीय निर्यात से पहले। लेनदेन या असमर्थता नियम को परिभाषित करें और परीक्षण करें जो रिकवरी को सुरक्षित बनाता है।
  4. किसी उपकरण का परिवर्तन करें inputSchemaइसकी विवरण को बदलने के बिना. पुष्टि पूरी तरह से वर्णक पिनिंग इसे पकड़ता है.
  5. एक नीति जोड़े जो सार्वजनिक कैशिंग से इनकार करती है जब tools/listमुख्य द्वारा भिन्न होता है।
  6. गेटवे के पीछे एक पुराने सर्वर का मॉडल। सभी हाथ पकड़ने और सत्र व्यवहार को स्पष्ट के पीछे डाल 2025-11-25संगतता शाखा।

प्रमुख शर्तें

TermMeaning
Metadata poisoningInstructions or deceptive claims embedded in a tool descriptor
Rug pullChange to a previously approved descriptor
Tool shadowingAmbiguous routing caused by duplicate unqualified names
Header mismatchRouting header and JSON-RPC body disagreement, error -32020
Hash pinDigest of the complete approved descriptor
MRTRStateless response and retry pattern for server-requested input
requestStateOpaque round-trip value that must be treated as untrusted input
Capability declarationStatement of protocol compatibility, not authorization
Implicit form supportAn empty elicitation capability object, equivalent to form support
Qualified tool nameStable gateway name such as notes.search

आगे पढ़ना

This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.

Browse the complete course catalog or open this lesson on GitHub.