ক্রস-অরিজিন XMLHttpRequest

নিয়মিত ওয়েব পৃষ্ঠাগুলি দূরবর্তী সার্ভার থেকে ডেটা পাঠাতে এবং গ্রহণ করতে XMLHttpRequest অবজেক্ট ব্যবহার করতে পারে, কিন্তু তারা একই মূল নীতি দ্বারা সীমাবদ্ধ। বিষয়বস্তু স্ক্রিপ্টগুলি ওয়েব উত্সের পক্ষ থেকে অনুরোধগুলি শুরু করে যে বিষয়বস্তু স্ক্রিপ্টটি প্রবেশ করানো হয়েছে এবং সেইজন্য সামগ্রী স্ক্রিপ্টগুলিও একই মূল নীতির অধীন৷ (কন্টেন্ট স্ক্রিপ্টগুলি Chrome 73 থেকে CORB এবং Chrome 83 থেকে CORS- এর অধীন।) এক্সটেনশনের উত্স এতটা সীমিত নয় - একটি এক্সটেনশনের পটভূমি পৃষ্ঠা বা ফোরগ্রাউন্ড ট্যাবে কার্যকর করা একটি স্ক্রিপ্ট তার উত্সের বাইরে দূরবর্তী সার্ভারের সাথে কথা বলতে পারে, যতক্ষণ না এক্সটেনশন ক্রস-অরিজিন অনুমতির অনুরোধ করে।

এক্সটেনশন উত্স

প্রতিটি চলমান এক্সটেনশন তার নিজস্ব পৃথক নিরাপত্তা মূলের মধ্যে বিদ্যমান। অতিরিক্ত সুবিধার অনুরোধ না করে, এক্সটেনশনটি তার ইনস্টলেশনের মধ্যে সংস্থান পেতে 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://*/" এর একটি ম্যাচ প্যাটার্ন HTTPS অ্যাক্সেসযোগ্য সমস্ত ডোমেনে অ্যাক্সেসের অনুমতি দেয়। মনে রাখবেন যে এখানে, মিলের নিদর্শনগুলি বিষয়বস্তু স্ক্রিপ্টের মিলের নিদর্শনগুলির অনুরূপ, তবে হোস্টকে অনুসরণ করা যে কোনও পথের তথ্য উপেক্ষা করা হয়৷

এছাড়াও নোট করুন যে অ্যাক্সেস হোস্ট এবং স্কিম দ্বারা উভয়ই দেওয়া হয়। যদি একটি এক্সটেনশন একটি প্রদত্ত হোস্ট বা হোস্টের সেটে নিরাপদ এবং অ-সুরক্ষিত HTTP অ্যাক্সেস চায়, তবে এটি অবশ্যই আলাদাভাবে অনুমতিগুলি ঘোষণা করতে হবে:

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

নিরাপত্তা বিবেচনা

ক্রস-সাইট স্ক্রিপ্টিং দুর্বলতা এড়ানো

XMLHttpRequest এর মাধ্যমে পুনরুদ্ধার করা সংস্থানগুলি ব্যবহার করার সময়, আপনার পটভূমি পৃষ্ঠাটি ক্রস-সাইট স্ক্রিপ্টিংয়ের শিকার না হওয়ার জন্য সতর্ক হওয়া উচিত। বিশেষত, নিচের মতো বিপজ্জনক API ব্যবহার করা এড়িয়ে চলুন:

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();

পরিবর্তে, নিরাপদ API পছন্দ করুন যা স্ক্রিপ্ট চালায় না:

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()));

উপরের পদ্ধতিতে, বিষয়বস্তু স্ক্রিপ্ট এক্সটেনশনকে এক্সটেনশনের অ্যাক্সেস আছে এমন যেকোনো URL আনতে বলতে পারে। একটি দূষিত ওয়েব পৃষ্ঠা এই ধরনের বার্তা জাল করতে সক্ষম হতে পারে এবং ক্রস-অরিজিন সংস্থানগুলিতে অ্যাক্সেস দেওয়ার জন্য এক্সটেনশনকে কৌশল করতে পারে৷

পরিবর্তে, মেসেজ হ্যান্ডলার ডিজাইন করুন যা সংগ্রহ করা যেতে পারে এমন সংস্থানগুলিকে সীমাবদ্ধ করে। নীচে, শুধুমাত্র সামগ্রী স্ক্রিপ্ট দ্বারা itemId দেওয়া হয়েছে, সম্পূর্ণ URL নয়।

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 => ...);

HTTP এর চেয়ে HTTPS পছন্দ করা

উপরন্তু, HTTP এর মাধ্যমে পুনরুদ্ধার করা সংস্থান সম্পর্কে বিশেষভাবে সতর্ক থাকুন। যদি আপনার এক্সটেনশনটি একটি প্রতিকূল নেটওয়ার্কে ব্যবহার করা হয়, তাহলে একজন নেটওয়ার্ক আক্রমণকারী (ওরফে একটি "মানুষ-ইন-দ্য-মিডল" ) প্রতিক্রিয়া পরিবর্তন করতে পারে এবং সম্ভাব্যভাবে, আপনার এক্সটেনশনকে আক্রমণ করতে পারে৷ পরিবর্তে, যখনই সম্ভব HTTPS পছন্দ করুন।

বিষয়বস্তু নিরাপত্তা নীতি সামঞ্জস্য করা

আপনি যদি আপনার ম্যানিফেস্টে একটি content_security_policy অ্যাট্রিবিউট যোগ করে অ্যাপ বা এক্সটেনশনের জন্য ডিফল্ট বিষয়বস্তু নিরাপত্তা নীতি পরিবর্তন করেন, তাহলে আপনাকে নিশ্চিত করতে হবে যে আপনি যে হোস্টের সাথে সংযোগ করতে চান তাদের অনুমতি দেওয়া হয়েছে। যদিও ডিফল্ট নীতি হোস্টের সাথে সংযোগগুলিকে সীমাবদ্ধ করে না, স্পষ্টভাবে connect-src বা default-src নির্দেশিকা যোগ করার সময় সতর্ক থাকুন।