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

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

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

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

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

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

क्रॉस-ऑरिजिन अनुमतियों के लिए अनुरोध करें

किसी एक्सटेंशन के ऑरिजिन से बाहर के रिमोट सर्वर के ऐक्सेस का अनुरोध करने के लिए, मेनिफ़ेस्ट फ़ाइल के 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() API, सर्विस वर्कर के बाहर के एक्सटेंशन में काम करता है और इसे कॉल करने से एक्सटेंशन सर्विस वर्कर के फ़ेच हैंडलर को ट्रिगर होता है. नया काम, जहां भी मुमकिन हो, 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 डायरेक्टिव को साफ़ तौर पर जोड़ते समय सावधानी बरतें.