iframe में मौजूद पासकी

कई डोमेन पर, कॉन्टेक्स्ट के हिसाब से आसानी से पुष्टि करने के लिए, संगठन अक्सर साइन-इन पेजों को iframe में एम्बेड करते हैं. हालांकि, तीसरे पक्ष के फ़्रेम में पुष्टि करने के कॉन्टेक्स्ट लोड करने से, उपयोगकर्ताओं को क्लिकजैकिंग (यूआई रीड्रेसिंग) और बिना अनुमति के क्रेडेंशियल बनाने जैसे गंभीर खतरों का सामना करना पड़ता है. इन जोखिमों को कम करने के लिए, ब्राउज़र डिफ़ॉल्ट रूप से क्रॉस-ऑरिजिन iframe में WebAuthn को बंद कर देते हैं. इस पाबंदी को सुरक्षित तरीके से हटाने के लिए, डिफ़ेंस-इन-डेप्थ प्रोटोकॉल का इस्तेमाल करना ज़रूरी है.

थ्रेट मॉडल की पहचान करना

सबफ़्रेम में पासकी (WebAuthn) चालू करने से पहले, यह समझ लें कि आपको किस तरह के गलत इस्तेमाल से बचना है:

  • छिपे हुए iframe इंजेक्शन का इस्तेमाल करके ट्रैकिंग करना: हमलावर, भरोसेमंद साइट पर मौजूद किसी विज्ञापन या विजेट का इस्तेमाल करके, अपने डोमेन से WebAuthn प्रॉम्प्ट को ट्रिगर करता है. इससे वह लोगों को बिना संदर्भ दिखाए, पासकी को अनुमति देने के लिए गुमराह करता है. इससे उपयोगकर्ता की पहचान को हमलावर के कंट्रोल वाले खाते से लिंक किया जाता है, ताकि डेटा इकट्ठा किया जा सके.
  • विज़ुअल ओवरले और क्लिकजैकिंग (यूज़र इंटरफ़ेस (यूआई) में बदलाव): इस तरह के हमले में, नुकसान पहुंचाने वाला पैरंट पेज, स्टैंडर्ड सीएसएस का इस्तेमाल करके पुष्टि करने वाले iframe को छिपा देता है. इसके बाद, पुष्टि करने की प्रोसेस को ट्रिगर करने वाले क्लिक को चुराने के लिए, नकली यूज़र इंटरफ़ेस (यूआई) एलिमेंट को ओवरले कर देता है. अगर उपयोगकर्ता गलती से प्रॉम्प्ट पूरा कर देता है, तो इससे सेशन हाइजैकिंग हो सकती है या बिना अनुमति के कार्रवाइयां की जा सकती हैं.

इन खतरों से बचने के लिए, यहां दिए गए सबसे सही तरीके अपनाएं:

टॉप-लेवल के दस्तावेज़ (टॉप फ़्रेम) के लिए:

एम्बेड किए गए दस्तावेज़ (iframe) के लिए:

दोनों दस्तावेज़ों के लिए:

Permissions Policy का इस्तेमाल करके, डेलिगेशन की सुविधा चालू करना

ब्राउज़र, डिफ़ॉल्ट रूप से क्रॉस-ऑरिजिन iframe में WebAuthn को ऐक्सेस करने की सुविधा ब्लॉक करते हैं. Permissions Policy एक ऐसा वेब प्लैटफ़ॉर्म है जो टॉप-लेवल के दस्तावेज़ को, इन सुविधाओं को भरोसेमंद तीसरे पक्ष के ऑरिजिन को साफ़ तौर पर सौंपने की अनुमति देता है.

सुविधा के टोकन

WebAuthn में दो अलग-अलग टोकन का इस्तेमाल होता है:

  • publickey-credentials-get: पासकी की मदद से साइन-इन करने की प्रोसेस (navigator.credentials.get()) के लिए अनुमति देता है.
  • publickey-credentials-create: पासकी रजिस्टर करने के फ़्लो (navigator.credentials.create()) के लिए अनुमति देता है.

इस सुविधा को चालू करने के लिए ज़रूरी शर्तें

इन सुविधाओं को चालू करने के लिए, पैरंट सर्वर के जवाब और क्लाइंट-साइड मार्कअप, दोनों में एक जैसा डेटा होना ज़रूरी है:

Permissions-Policy: publickey-credentials-get=(self "https://embedded-auth.example.com")

Permissions Policy: publickey-credentials-get compatibility:

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: not supported.
  • Safari: not supported.

Source

Permissions Policy: publickey-credentials-create compatibility:

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: not supported.
  • Safari: not supported.

Source

  • एचटीएमएल allow एट्रिब्यूट: एचटीएमएल मार्कअप में, <iframe> एलिमेंट को यह भी एलान करना होगा कि यह सुविधा चालू है.
<iframe src="https://embedded-auth.example.com?nonce=deadbeef12345678&client=https%3A%2F%2Fembedded-auth.example.com" allow="publickey-credentials-get"></iframe>

iframe allow="publickey-credentials-get" की ज़रूरी शर्तें:

Browser Support

  • Chrome: 84.
  • Edge: 84.
  • Firefox: 118.
  • Safari: not supported.

iframe allow="publickey-credentials-create" compatibility:

Browser Support

  • Chrome: not supported.
  • Edge: not supported.
  • Firefox: 123.
  • Safari: not supported.

पार्टिशन की गई तीसरे पक्ष की कुकी चालू करना

पुष्टि करने का फ़्लो भरोसेमंद हो, इसके लिए एम्बेड किए गए क्रॉस-ऑरिजिन iframe में एक सेशन शुरू किया जाना चाहिए और उसे बनाए रखा जाना चाहिए. आधुनिक ब्राउज़र, तीसरे पक्ष की कुकी के इस्तेमाल पर सख्त पाबंदियां लगाते हैं. इसलिए, सामान्य परसिस्टेंस मैकेनिज़्म अक्सर डिफ़ॉल्ट रूप से ब्लॉक हो जाते हैं. साथ ही, ऐक्सेस पाने के लिए Storage Access API को कॉल करना पड़ सकता है.

इन समस्याओं को कम करने के लिए, अपनी सेशन कुकी को SameSite: None, Secure, और Partitioned एट्रिब्यूट के साथ कॉन्फ़िगर करें. यह यूनीफ़ाइड प्लैटफ़ॉर्म मैकेनिज़्म, ब्राउज़र-लेवल की निजता सेटिंग का पालन करते हुए, iframe में लगातार स्थिति बनाए रखता है.

सेट SameSite: None

SameSite: None यह कुकी को दूसरी साइट से ऐक्सेस करने के लिए साफ़ तौर पर मार्क करता है, ताकि इसे तीसरे पक्ष के कॉन्टेक्स्ट (जैसे, iframe) से किए गए अनुरोधों के साथ भेजा जा सके. यह एट्रिब्यूट, कुकी के लिए ज़रूरी है, ताकि वे अलग-अलग ऑरिजिन के साथ काम कर सकें. हालांकि, मॉडर्न ब्राउज़र से स्वीकार किए जाने के लिए, इसे Secure एट्रिब्यूट के साथ जोड़ना ज़रूरी है.

सेट Partitioned

Partitioned एट्रिब्यूट, कुकी को सीएचआईपीएस (कुकीज़ हैविंग इंडिपेंडेंट पार्टिशन्ड स्टेट) में ऑप्ट इन करता है. इससे कुकी को हर टॉप-लेवल साइट के लिए अलग से सेव किया जा सकता है. इससे यह पक्का होता है कि कुकी, तीसरे पक्ष के खास iframe कॉन्टेक्स्ट में ऐक्सेस की जा सकती है. इससे क्रॉस-साइट ट्रैकिंग चालू किए बिना, सेशन की स्थिति को बनाए रखने में मदद मिलती है. उपयोगकर्ता को अलग-अलग साइटों पर मौजूद हर एम्बेड के लिए, फिर से साइन इन करना होगा.

कॉन्टेंट की सुरक्षा के लिए नीति का इस्तेमाल करके एंडपॉइंट को सुरक्षित रखना

अनुमतियों के बारे में नीति यह तय करती है कि आपका iframe WebAuthn को चला सकता है या नहीं. वहीं, कॉन्टेंट की सुरक्षा के बारे में नीति (सीएसपी) यह तय करती है कि किसे आपके iframe को होस्ट करने की अनुमति है.

पुष्टि करने वाले एंडपॉइंट के लिए, यह पक्का करना ज़रूरी है कि सिर्फ़ भरोसेमंद पार्टनर साइटें या आपकी प्रॉपर्टी, लॉगिन सबफ़्रेम को लोड कर सकें. साथ ही, बिना अनुमति के क्लिकजैकिंग की कोशिशों को यूज़र इंटरफ़ेस (यूआई) लोड होने से पहले ही बंद कर दें.

frame-ancestors का इस्तेमाल करें

frame-ancestors निर्देश उन मान्य पैरंट पेजों के बारे में बताता है जो आपकी साइट को एम्बेड कर सकते हैं. इस डायरेक्टिव में डोमेन जोड़कर, उन डोमेन को अनुमति दी जा सकती है जिन्हें लॉगिन सबफ़्रेम को एम्बेड करने की अनुमति है.

Content-Security-Policy: frame-ancestors 'self' https://parent-site.example.com;

कॉन्टेंट की सुरक्षा के बारे में नीति: फ़्रेम-ऐनसेस्टर के साथ काम करने की सुविधा:

Browser Support

  • Chrome: 40.
  • Edge: 15.
  • Firefox: 58.
  • Safari: 10.

Source

सेट X-Frame-Options

लेगसी X-Frame-Options हेडर में भी ऐसी ही सुविधा मिलती है. हालांकि, इसमें सिर्फ़ बाइनरी विकल्प (DENY या SAMEORIGIN) इस्तेमाल किए जा सकते हैं. अगर ब्राउज़र में सीएसपी काम नहीं करता है, तो सीएसपी frame-ancestors और X-Frame-Options: DENY, दोनों को सेट करें. सीएसपी की सुविधा उपलब्ध होने पर, इसे हमेशा प्राथमिकता दी जाती है.

X-Frame-Options: DENY

X-Frame-Options के साथ काम करने की सुविधा:

Browser Support

  • Chrome: 4.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 4.

Source

भरोसा करें, लेकिन सर्वर-साइड पर पुष्टि करें

ब्राउज़र के क्लाइंट-साइड चेक, इरादे और अनुमतियों का आकलन करते हैं. हालांकि, सर्वर ही भरोसेमंद होने का फ़ैसला करता है. भरोसेमंद पार्टी (आरपी) के सर्वर पर जवाब की पुष्टि करें, ताकि यह पक्का किया जा सके कि कॉन्टेक्स्ट मान्य है और उस पर हस्ताक्षर किया गया है.

क्लाइंट-डेटा पेलोड

WebAuthn क्लाइंट डेटा में ऐसे पैरामीटर शामिल होते हैं जिन्हें खास तौर पर आपकी मदद करने के लिए डिज़ाइन किया गया है. इनकी मदद से, iframe में किए गए अनुरोध के कॉन्टेक्स्ट की पुष्टि की जा सकती है:

  • crossOrigin (बूलियन): इससे पता चलता है कि WebAuthn API को किसी दूसरे ऑरिजिन वाले iframe में शुरू किया गया था या नहीं. अगर आपका आर्किटेक्चर iframe पर निर्भर करता है, तो आपके सर्वर को यह ज़रूर लागू करना चाहिए कि यह फ़्लैग true है.
  • topOrigin (string): टॉप-लेवल ब्राउज़िंग कॉन्टेक्स्ट का ऑरिजिन (ब्राउज़र के पता बार में क्या दिखता है). सर्वर को, माता-पिता के जाने-पहचाने और आधिकारिक ऑरिजिन की सूची के हिसाब से इसकी पुष्टि ज़रूर करनी चाहिए.

पुष्टि करने के लिए चेकलिस्ट

अपने सर्वर पर पुष्टि करने वाले ऐप्लिकेशन के जवाब की पुष्टि करने के लिए, यह तरीका अपनाएं:

  1. ऑथेंटिकेटर के जवाब से मिले, हस्ताक्षर किए गए collectedClientData को पार्स और डिकोड करें.
  2. पक्का करें कि type, सेरेमनी (webauthn.get या webauthn.create) से मेल खाता हो.
  3. उपयोगकर्ता की मौजूदगी और हस्ताक्षर की पुष्टि करें.
  4. अगर अनुरोध, iframe स्ट्रक्चर से आना था, तो:
    • crossOrigin === true लागू करें.
    • यह पक्का करें कि topOrigin, माता-पिता के ऑरिजिन की अनुमति वाली सूची से मेल खाता हो.

postMessage() का इस्तेमाल करके, सेशन को सुरक्षित तरीके से सेट अप करना

सेशन को भरोसेमंद तरीके से सेट अप करने के लिए, iframe को postMessage() का इस्तेमाल करके, पुष्टि करने वाले टोकन को वापस पैरंट पेज पर भेजना होगा. इससे पैरंट पेज, पहले-पक्ष के अपने कॉन्टेक्स्ट में सेशन की स्थिति को मैनेज कर पाएगा.

सुरक्षित वर्कफ़्लो

सुरक्षित सेशन बनाने के लिए, यह वर्कफ़्लो अपनाएं:

  1. पक्का करें कि iframe src यूआरएल में nonce और origin क्वेरी पैरामीटर शामिल हों:
    • nonce के लिए कोई रैंडम वैल्यू इस्तेमाल करें. nonce, सुरक्षा की पुष्टि करने वाले टोकन के तौर पर काम करता है. इससे यह पक्का किया जाता है कि iframe से मिला पुष्टि करने वाला टोकन, पैरंट पेज से शुरू किए गए सेशन से सही तरीके से मैच करता है.
    • origin के लिए, पैरंट फ़्रेम डोमेन का इस्तेमाल करें. origin पैरामीटर, पैरंट पेज के ऑरिजिन के बारे में बताता है. इससे iframe को उस कॉन्टेक्स्ट की सुरक्षित तरीके से पहचान करने में मदद मिलती है जिसमें उसे एम्बेड किया गया है.
  2. यह iframe, अपने सर्वर से WebAuthn की पुष्टि करता है.
  3. आईफ़्रेम सर्वर, JWT जैसा टोकन जारी करता है. इसमें nonce शामिल होता है और इसे पैरंट पेज पर फ़ॉरवर्ड किया जाता है.

    // Extract nonce and origin from the URL params
    const urlParams = new URLSearchParams(window.location.search);
    const nonce = urlParams.get('nonce');
    const origin = urlParams.get('origin');
    if (!nonce || !origin) {
      alert('Nonce or origin is missing in the URL');
      return;
    }
    
    // Create a JWT
    const response = await post('/createToken', { nonce, origin });
    const token = response.token;
    
    // Post the JWT to the parent frame
    window.parent.postMessage({ token }, origin);
    
  4. पैरंट पेज, message इवेंट के लिए लिसन करता है. साथ ही, भेजने वाले के ऑरिजिन की पुष्टि करता है और टोकन की पुष्टि करता है.

    window.addEventListener("message", (event) => {
      if (event.origin !== "https://embedded-auth.example.com") return;
      // Verify the received JWT
      const result = await post('/verifyIdToken', {
        token: event.data.token,
        origin: provider.origin,
      });
    });
    
  5. अगर JWT की पुष्टि हो जाती है, तो पैरंट पेज सेशन को बनाए रखता है.

भेजने वाले और पाने वाले, दोनों की सुरक्षा से जुड़ी ज़िम्मेदारियां होती हैं:

  • भेजने वाला (आईफ़्रेम): मैसेज भेजते समय, हमेशा टारगेट ऑरिजिन की जानकारी दें. "*" का इस्तेमाल कभी न करें.
  • पाने वाला (माता-पिता): मैसेज पाने पर, हमेशा event.origin की पुष्टि करें, ताकि ओरिजन स्पूफ़िंग को रोका जा सके.

नतीजा

सुरक्षित iframe का इस्तेमाल इन बातों पर निर्भर करता है: चालू करने के लिए अनुमतियों से जुड़ी नीति, पाबंदी लगाने के लिए सीएसएपी, सेशन को बनाए रखने के लिए तीसरे पक्ष की पार्टीशन की गई कुकी, क्लाइंट के कॉन्टेक्स्ट की सर्वर-साइड पुष्टि, और postMessage() का इस्तेमाल करके कॉन्टेक्स्ट अवेयर सेशन हैंडऑफ़.

मिलते-जुलते विषयों के बारे में ज़्यादा जानने के लिए, Google के Chrome डेवलपर ब्लॉग को फ़ॉलो करें. साथ ही, Chrome डेवलपर आइडेंटिटी के दस्तावेज़ में जाकर ज़्यादा संसाधन देखें.