ক্রস-অরিজিন নেটওয়ার্ক অনুরোধ

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

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

প্রতিটি চলমান এক্সটেনশন তার নিজস্ব পৃথক নিরাপত্তা মূলের মধ্যে বিদ্যমান। অতিরিক্ত সুবিধার অনুরোধ না করে, এক্সটেনশন তার ইনস্টলেশনের মধ্যে সংস্থান পেতে fetch() কল করতে পারে। উদাহরণস্বরূপ, যদি একটি এক্সটেনশনে config.json নামক একটি JSON কনফিগারেশন ফাইল থাকে, একটি config_resources/ ফোল্ডারে, এক্সটেনশনটি ফাইলের বিষয়বস্তু এইভাবে পুনরুদ্ধার করতে পারে:

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

যদি এক্সটেনশনটি নিজের ব্যতীত অন্য কোনও সুরক্ষা উত্স ব্যবহার করার চেষ্টা করে, https://www.google.com বলুন, যদি এক্সটেনশনটি যথাযথ ক্রস-অরিজিন অনুমতির অনুরোধ না করে তবে ব্রাউজার এটিকে অনুমোদন করে না৷

ক্রস-অরিজিন অনুমতির অনুরোধ করুন

একটি এক্সটেনশনের মূলের বাইরে দূরবর্তী সার্ভারগুলিতে অ্যাক্সেসের অনুরোধ করতে, ম্যানিফেস্ট ফাইলের হোস্ট_অনুমতি বিভাগে হোস্ট, ম্যাচ প্যাটার্ন বা উভয়ই যোগ করুন।

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

ক্রস-অরিজিন অনুমতি মান সম্পূর্ণরূপে যোগ্য হোস্ট নাম হতে পারে, যেমন:

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

অথবা এগুলি মিলের নিদর্শন হতে পারে, যেমন:

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

"https://*/" এর একটি ম্যাচ প্যাটার্ন HTTPS অ্যাক্সেসযোগ্য সমস্ত ডোমেনে অ্যাক্সেসের অনুমতি দেয়। মনে রাখবেন যে এখানে, মিলের নিদর্শনগুলি বিষয়বস্তু স্ক্রিপ্টের মিলের নিদর্শনগুলির অনুরূপ, তবে হোস্টকে অনুসরণ করা যে কোনও পথের তথ্য উপেক্ষা করা হয়৷

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

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

আনয়ন() বনাম XMLHttpRequest()

fetch() বিশেষভাবে পরিষেবা কর্মীদের জন্য তৈরি করা হয়েছে এবং সিঙ্ক্রোনাস অপারেশন থেকে দূরে একটি বৃহত্তর ওয়েব প্রবণতা অনুসরণ করে। XMLHttpRequest() API পরিষেবা কর্মীর বাইরের এক্সটেনশনগুলিতে সমর্থিত, এবং এটিকে কল করলে এক্সটেনশন পরিষেবা কর্মীর ফেচ হ্যান্ডলারকে ট্রিগার করে৷ যেখানেই সম্ভব নতুন কাজ fetch() পক্ষে থাকা উচিত।

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

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

fetch() মাধ্যমে পুনরুদ্ধার করা সংস্থানগুলি ব্যবহার করার সময়, আপনার অফস্ক্রিন নথি, সাইড প্যানেল বা পপআপ ক্রস-সাইট স্ক্রিপ্টিংয়ের শিকার না হওয়ার জন্য সতর্ক হওয়া উচিত। বিশেষত, innerHTML এর মতো বিপজ্জনক API ব্যবহার করা এড়িয়ে চলুন। যেমন:

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

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

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

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

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

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

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

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

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

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