क्रॉस-ऑरिजिन XMLHttpRequest

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

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

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

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handleStateChange; // Implemented elsewhere.
xhr.open("GET", chrome.extension.getURL('/config_resources/config.json'), true);
xhr.send();

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

क्रॉस-ऑरिजिन की अनुमतियों का अनुरोध किया जा रहा है

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

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

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

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

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

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

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

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

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

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

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

XMLHttpRequest से मिले संसाधनों का इस्तेमाल करते समय, आपके बैकग्राउंड पेज को इन बातों का ध्यान रखना चाहिए क्रॉस-साइट स्क्रिप्टिंग के शिकार हो जाते हैं. खास तौर पर, खतरनाक एपीआई इस्तेमाल करने से बचें. जैसे, नीचे दिया गया है:

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // WARNING! Might be evaluating an evil script!
    var resp = eval("(" + xhr.responseText + ")");
    ...
  }
}
xhr.send();
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // WARNING! Might be injecting a malicious script!
    document.getElementById("resp").innerHTML = xhr.responseText;
    ...
  }
}
xhr.send();

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

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // JSON.parse does not evaluate the attacker's scripts.
    var resp = JSON.parse(xhr.responseText);
  }
}
xhr.send();
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // innerText does not let the attacker inject HTML elements.
    document.getElementById("resp").innerText = xhr.responseText;
  }
}
xhr.send();

कॉन्टेंट स्क्रिप्ट का ऐक्सेस, क्रॉस-ऑरिजिन अनुरोधों तक सीमित रखना

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

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

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') {
        var 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 डायरेक्टिव जोड़ते समय सावधानी बरतें.