क्रॉस-ऑरिजिन नेटवर्क के अनुरोध

सामान्य वेब पेज, रिमोट सर्वर से डेटा भेजने और पाने के लिए, fetch() या XMLHttpRequest एपीआई का इस्तेमाल कर सकते हैं. हालांकि, ये एक ही सोर्स की नीति से सीमित होते हैं. कॉन्टेंट स्क्रिप्ट, उस वेब ऑरिजिन की ओर से अनुरोध शुरू करती हैं जिसमें कॉन्टेंट स्क्रिप्ट को इंजेक्ट किया गया है. इसलिए, कॉन्टेंट स्क्रिप्ट पर भी एक ही ऑरिजिन की नीति लागू होती है. एक्सटेंशन के ऑरिजिन सीमित नहीं होते. एक्सटेंशन सर्विस वर्कर या फ़ोरग्राउंड टैब में चल रही स्क्रिप्ट, अपने ऑरिजिन से बाहर के रिमोट सर्वर से तब तक बात कर सकती है, जब तक एक्सटेंशन क्रॉस-ऑरिजिन अनुमतियों का अनुरोध करता है.

एक्सटेंशन का ऑरिजिन

चल रहे हर एक्सटेंशन का अपना अलग सुरक्षा ऑरिजिन होता है. अतिरिक्त खास अधिकारों का अनुरोध किए बिना, एक्सटेंशन fetch() को कॉल कर सकता है, ताकि उसे इंस्टॉल करने के दौरान संसाधन मिल सकें. उदाहरण के लिए, अगर किसी एक्सटेंशन में config_resources/ फ़ोल्डर में config.json नाम की JSON कॉन्फ़िगरेशन फ़ाइल है, तो एक्सटेंशन इस तरह फ़ाइल का कॉन्टेंट वापस ला सकता है:

const response = await fetch('/config_resources/config.json');
const jsonData = await response.json();

अगर एक्सटेंशन, अपने अलावा किसी दूसरे सुरक्षा ऑरिजिन का इस्तेमाल करने की कोशिश करता है, जैसे कि https://www.google.com, तो ब्राउज़र उसे अनुमति नहीं देता. ऐसा तब तक होता है, जब तक एक्सटेंशन ने क्रॉस-ऑरिजिन अनुमतियों का अनुरोध न कर दिया हो.

अलग-अलग डोमेन से अनुमतियों का अनुरोध करना

किसी एक्सटेंशन के ऑरिजिन से बाहर के रिमोट सर्वर का ऐक्सेस पाने का अनुरोध करने के लिए, manifest फ़ाइल के host_permissions सेक्शन में होस्ट, मैच पैटर्न या दोनों जोड़ें.

{
  "name": "My extension",
  ...
  "host_permissions": [
    "https://www.google.com/"
  ],
  ...
}

क्रॉस-ऑरिजिन अनुमति की वैल्यू, होस्ट के पूरी तरह क्वालिफ़ाइड नेम हो सकते हैं. जैसे:

  • "https://www.google.com/"
  • "https://www.gmail.com/"

इसके अलावा, ये मैच पैटर्न भी हो सकते हैं:

  • "https://*.google.com/"
  • "https://*/"

"https://*/" से मैच करने वाले पैटर्न से, उन सभी डोमेन को एचटीटीपीएस ऐक्सेस करने की अनुमति मिलती है जिन तक पहुंचा जा सकता है. ध्यान दें कि यहां मैच पैटर्न, कॉन्टेंट स्क्रिप्ट मैच पैटर्न से मिलते-जुलते हैं. हालांकि, होस्ट के बाद मौजूद पाथ की जानकारी को अनदेखा किया जाता है.

यह भी ध्यान रखें कि ऐक्सेस, होस्ट और स्कीम, दोनों से मिलता है. अगर किसी एक्सटेंशन को किसी होस्ट या होस्ट के सेट का सुरक्षित और असुरक्षित, दोनों तरह का एचटीटीपी ऐक्सेस चाहिए, तो उसे अनुमतियों का एलान अलग-अलग करना होगा:

"host_permissions": [
  "http://www.google.com/",
  "https://www.google.com/"
]

Fetch() बनाम XMLHttpRequest()

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

सुरक्षा से जुड़ी बातें

क्रॉस-साइट स्क्रिप्टिंग जोखिम की आशंकाओं से बचें

fetch() से मिले संसाधनों का इस्तेमाल करते समय, अपने ऑफ़स्क्रीन दस्तावेज़, साइड पैनल या पॉप-अप को ध्यान रखें कि क्रॉस-साइट स्क्रिप्टिंग का शिकार न हो. खास तौर पर, innerHTML जैसे खतरनाक एपीआई का इस्तेमाल करने से बचें. उदाहरण के लिए:

const response = await fetch("https://api.example.com/data.json");
const jsonData = await response.json();
// WARNING! Might be injecting a malicious script!
document.getElementById("resp").innerHTML = jsonData;
    ...

इसके बजाय, ऐसे सुरक्षित एपीआई इस्तेमाल करें जो स्क्रिप्ट नहीं चलाते:

const response = await fetch("https://api.example.com/data.json");
const jsonData = await response.json();
// JSON.parse does not evaluate the attacker's scripts.
let resp = JSON.parse(jsonData);

const response = await fetch("https://api.example.com/data.json");
const jsonData = response.json();
// textContent does not let the attacker inject HTML elements.
document.getElementById("resp").textContent = jsonData;

अलग-अलग डोमेन से किए जाने वाले अनुरोधों के लिए, कॉन्टेंट स्क्रिप्ट के ऐक्सेस को सीमित करना

किसी कॉन्टेंट स्क्रिप्ट की ओर से क्रॉस-ऑरिजिन अनुरोध करते समय, नुकसान पहुंचाने वाले वेब पेजों से सावधान रहें. ये पेज, कॉन्टेंट स्क्रिप्ट के नाम पर काम कर सकते हैं. खास तौर पर, कॉन्टेंट स्क्रिप्ट को आर्बिट्ररी यूआरएल का अनुरोध करने की अनुमति न दें.

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

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.contentScriptQuery == 'fetchUrl') {
      // WARNING: SECURITY PROBLEM - a malicious web page may abuse
      // the message handler to get access to arbitrary cross-origin
      // resources.
      fetch(request.url)
        .then(response => response.text())
        .then(text => sendResponse(text))
        .catch(error => ...)
      return true;  // Will respond asynchronously.
    }
  }
);
chrome.runtime.sendMessage(
  {
    contentScriptQuery: 'fetchUrl',
    url: `https://another-site.com/price-query?itemId=${encodeURIComponent(request.itemId)}`
  },
  response => parsePrice(response.text())
);

ऊपर बताए गए तरीके में, कॉन्टेंट स्क्रिप्ट, एक्सटेंशन से किसी भी ऐसे यूआरएल को फ़ेच करने के लिए कह सकती है जिसका ऐक्सेस एक्सटेंशन के पास है. नुकसान पहुंचाने वाला कोई वेब पेज, इस तरह के मैसेज बना सकता है और एक्सटेंशन को गुमराह करके, क्रॉस-ऑरिजिन संसाधनों का ऐक्सेस दे सकता है.

इसके बजाय, ऐसे मैसेज हैंडलर डिज़ाइन करें जो फ़ेच किए जा सकने वाले संसाधनों को सीमित करते हैं. नीचे, कॉन्टेंट स्क्रिप्ट से सिर्फ़ itemId दिया गया है, पूरा यूआरएल नहीं.

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.contentScriptQuery == 'queryPrice') {
      const url = `https://another-site.com/price-query?itemId=${encodeURIComponent(request.itemId)}`
      fetch(url)
        .then(response => response.text())
        .then(text => parsePrice(text))
        .then(price => sendResponse(price))
        .catch(error => ...)
      return true;  // Will respond asynchronously.
    }
  }
);
chrome.runtime.sendMessage(
  {contentScriptQuery: 'queryPrice', itemId: 12345},
  price => ...
);

एचटीटीपी के बजाय एचटीटीपीएस को प्राथमिकता दें

इसके अलावा, एचटीटीपी के ज़रिए वापस लाए गए संसाधनों के लिए खास तौर पर सावधानी बरतें. अगर आपके एक्सटेंशन का इस्तेमाल किसी ऐसे नेटवर्क पर किया जाता है जो आपके लिए खतरनाक है, तो नेटवर्क हमलावर (जिसे "man-in-the-middle" भी कहा जाता है) जवाब में बदलाव कर सकता है. साथ ही, आपके एक्सटेंशन पर हमला भी कर सकता है. इसके बजाय, जब भी हो सके एचटीटीपीएस का इस्तेमाल करें.

कॉन्टेंट की सुरक्षा के लिए बनी नीति में बदलाव करना

अगर आपने अपने एक्सटेंशन के लिए, डिफ़ॉल्ट कॉन्टेंट सुरक्षा नीति में बदलाव किया है, तो आपको यह पक्का करना होगा कि जिन होस्ट से आपको कनेक्ट करना है उनके लिए अनुमति दी गई हो. ऐसा करने के लिए, आपको अपने मेनिफ़ेस्ट में content_security_policy एट्रिब्यूट जोड़ना होगा. डिफ़ॉल्ट नीति, होस्ट से कनेक्ट करने पर पाबंदी नहीं लगाती. हालांकि, connect-src या default-src डायरेक्टिव को साफ़ तौर पर जोड़ते समय सावधानी बरतें.