افزونهها به امتیازات ویژهای در مرورگر دسترسی دارند و همین امر آنها را به هدف جذابی برای مهاجمان تبدیل میکند. اگر یک افزونه به خطر بیفتد، هر کاربر آن افزونه در برابر نفوذ مخرب و ناخواسته آسیبپذیر میشود. با بهکارگیری این شیوهها، افزونه و کاربران آن را ایمن نگه دارید.
محافظت از حسابهای توسعهدهندگان
کد افزونه از طریق حسابهای گوگل آپلود و بهروزرسانی میشود. اگر حسابهای توسعهدهندگان به خطر بیفتد، یک مهاجم میتواند کد مخرب را مستقیماً به همه کاربران ارسال کند. با فعال کردن احراز هویت دو مرحلهای ، ترجیحاً با یک کلید امنیتی ، از این حسابها محافظت کنید.
از نقشهای عضو مناسب استفاده کنید
اگر ناشر شما چندین عضو دارد، مطمئن شوید که نقشی که به هر کاربر داده شده مناسب است.
هرگز از HTTP استفاده نکنید
هنگام درخواست یا ارسال داده، از اتصال HTTP خودداری کنید. فرض کنید که هرگونه اتصال HTTP دارای استراق سمع یا حاوی تغییرات خواهد بود. HTTPS همیشه باید ترجیح داده شود، زیرا دارای امنیت داخلی است که اکثر حملات مرد میانی را دور میزند.
درخواست حداقل مجوزها
مرورگر کروم دسترسی افزونهها را به مجوزهایی که صریحاً در مانیفست درخواست شدهاند، محدود میکند. افزونهها باید مجوزهای خود را با ثبت APIها و وبسایتهایی که به آنها وابسته هستند، به حداقل برسانند.
محدود کردن امتیازات یک افزونه، سوءاستفادههای احتمالی یک مهاجم را محدود میکند.
واکشی متقابل مبدا ()
یک افزونه فقط میتواند fetch() و XMLHttpRequest() برای دریافت منابع از افزونه و از دامنههای مشخص شده در مجوزها استفاده کند. توجه داشته باشید که فراخوانیهای هر دو توسط fetch handler در service worker متوقف میشوند.
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"host_permissions": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"manifest_version": 3
}
این افزونه در نمونه بالا با فهرست کردن "https://developer.chrome.com/*" و "https://*.google.com/*" در مجوزها، درخواست دسترسی به هر چیزی در developer.chrome.com و زیردامنههای گوگل را دارد. اگر این افزونه مورد نفوذ قرار گیرد، همچنان فقط اجازه تعامل با وبسایتهایی را خواهد داشت که الگوی مطابقت را رعایت میکنند. مهاجم فقط توانایی محدودی برای دسترسی به "https://user_bank_info.com" یا تعامل با "https://malicious_website.com" خواهد داشت.
محدود کردن فیلدهای مانیفست
گنجاندن کلیدها و مجوزهای غیرضروری در مانیفست، آسیبپذیریهایی ایجاد میکند و افزونه را بیشتر در معرض دید قرار میدهد. فیلدهای مانیفست را به مواردی که افزونه به آنها متکی است محدود کنید.
قابل اتصال خارجی
از فیلد "externally_connectable" برای اعلام اینکه افزونه با کدام افزونههای خارجی و صفحات وب تبادل اطلاعات خواهد کرد، استفاده کنید. محدود کردن افرادی که افزونه میتواند از خارج با آنها ارتباط برقرار کند به منابع معتبر.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"https://developer.chrome.com/*",
"https://*.google.com/*"
],
"accepts_tls_channel_id": false
},
...
}
منابع قابل دسترسی در وب
دسترسی به منابع از طریق وب، در زیر بخش "web_accessible_resources" باعث میشود که یک افزونه توسط وبسایتها و مهاجمان قابل شناسایی باشد.
{
...
"web_accessible_resources": [
{
"resources": [ "test1.png", "test2.png" ],
"matches": [ "https://web-accessible-resources-1.glitch.me/*" ]
}
]
...
}
هرچه منابع وب قابل دسترسی بیشتری در دسترس باشد، راههای بیشتری برای سوءاستفاده مهاجمان بالقوه وجود دارد. این فایلها را به حداقل برسانید.
یک سیاست امنیتی محتوای صریح را لحاظ کنید
برای جلوگیری از حملات اسکریپتنویسی بینسایتی، یک سیاست امنیتی محتوا برای افزونه در مانیفست قرار دهید. اگر افزونه فقط منابع را از خودش بارگذاری میکند، موارد زیر را ثبت کنید:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "default-src 'self'"
},
"manifest_version": 3
}
اگر افزونه نیاز به استفاده از وب اسمبلی داشته باشد، یا محدودیتهای صفحات سندباکس را افزایش دهد، میتوان آنها را اضافه کرد:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';",
"sandboxed_pages":"script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
},
"manifest_version": 3
}
از document.write() و innerHTML اجتناب کنید
اگرچه ممکن است ایجاد پویای عناصر HTML با document.write() و innerHTML سادهتر باشد، اما افزونه و صفحات وبی که افزونه به آنها وابسته است را در معرض مهاجمانی قرار میدهد که اسکریپتهای مخرب را وارد میکنند. در عوض، گرههای DOM را به صورت دستی ایجاد کنید و innerText برای وارد کردن محتوای پویا استفاده کنید.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
از اسکریپتهای محتوا با دقت استفاده کنید
اگرچه اسکریپتهای محتوا در یک دنیای ایزوله زندگی میکنند، اما از حملات مصون نیستند:
- اسکریپتهای محتوا تنها بخشی از یک افزونه هستند که مستقیماً با صفحه وب تعامل دارند. به همین دلیل، صفحات وب متخاصم ممکن است بخشهایی از DOM را که اسکریپت محتوا به آن وابسته است، دستکاری کنند یا از رفتارهای استاندارد وب غافلگیرکننده، مانند موارد نامگذاری شده، سوءاستفاده کنند.
- برای تعامل با DOM صفحات وب، اسکریپتهای محتوا باید در همان فرآیند رندر صفحه وب اجرا شوند. این امر اسکریپتهای محتوا را در برابر نشت دادهها از طریق حملات کانال جانبی (مثلاً Spectre ) و در صورت به خطر افتادن فرآیند رندر توسط یک صفحه وب مخرب، در معرض خطر تصاحب توسط مهاجم قرار میدهد.
عملیاتی که از دادههای حساس (مانند اطلاعات خصوصی کاربر) یا APIهای کروم با دسترسی به توابع مرورگر استفاده میکنند، باید در سرویس ورکر افزونهها انجام شوند. از افشای تصادفی امتیازات افزونه به اسکریپتهای محتوا خودداری کنید:
- فرض کنید که پیامهای یک اسکریپت محتوا ممکن است توسط یک مهاجم ساخته شده باشند (مثلاً تمام ورودیها را اعتبارسنجی و پاکسازی کنید و اسکریپتهای خود را از اسکریپتنویسی بینسایتی محافظت کنید).
- فرض کنید هر دادهای که به اسکریپت محتوا ارسال میشود، ممکن است به صفحه وب نشت کند. دادههای حساس (مثلاً اطلاعات محرمانه از افزونه، دادههای سایر منابع وب، تاریخچه مرور) را به اسکریپتهای محتوا ارسال نکنید.
- دامنه اقدامات دارای امتیازی که میتوانند توسط اسکریپتهای محتوا اجرا شوند را محدود کنید. به اسکریپتهای محتوا اجازه ندهید که درخواستها را به URLهای دلخواه ارسال کنند یا آرگومانهای دلخواه را به APIهای افزونه ارسال کنند (مثلاً اجازه ندهید URLهای دلخواه به متدهای
fetch()یاchrome.tabs.create()ارسال شوند).
ثبت و پاکسازی ورودیها
با محدود کردن شنوندهها به آنچه افزونه انتظار دارد، اعتبارسنجی فرستندههای دادههای ورودی و پاکسازی تمام ورودیها، از یک افزونه در برابر اسکریپتهای مخرب محافظت کنید.
یک افزونه فقط در صورتی باید برای runtime.onMessageExternal ثبت نام کند که انتظار ارتباط از یک وبسایت یا افزونه خارجی را داشته باشد. همیشه تأیید کنید که فرستنده با یک منبع قابل اعتماد مطابقت دارد.
// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id === kFriendlyExtensionId)
doSomething();
});
حتی پیامهایی که از طریق رویداد runtime.onMessage از خود افزونه ارسال میشوند نیز باید به دقت بررسی شوند تا اطمینان حاصل شود که MessageSender از یک اسکریپت محتوای آسیبپذیر نباشد.
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});