Расширения имеют доступ к особым привилегиям в браузере, что делает их привлекательной целью для злоумышленников. Если расширение взломано, каждый пользователь этого расширения становится уязвимым для злонамеренного и нежелательного вторжения. Обеспечьте безопасность расширения и защиту его пользователей, применяя эти методы.
Защитите учетные записи разработчиков
Код расширения загружается и обновляется через учетные записи Google. Если учетные записи разработчиков будут скомпрометированы, злоумышленник может передать вредоносный код непосредственно всем пользователям. Защитите эти учетные записи, создав учетные записи специально для разработчиков и включив двухфакторную аутентификацию , желательно с ключом безопасности .
Делайте группы выборочными
Если вы используете групповую публикацию , оставьте группу только доверенным разработчикам. Не принимайте заявки на членство от неизвестных лиц.
Никогда не используйте HTTP, никогда
При запросе или отправке данных избегайте HTTP-соединения. Предположим, что любые HTTP-соединения будут перехватывать или содержать модификации. Всегда следует отдавать предпочтение HTTPS, поскольку он имеет встроенную систему безопасности, позволяющую обойти большинство атак «человек посередине» .
Запросить минимальные разрешения
Браузер Chrome ограничивает доступ расширения к привилегиям, явно запрошенным в манифесте . Расширения должны минимизировать свои разрешения, регистрируя только API и веб-сайты, от которых они зависят. Произвольный код должен быть сведен к минимуму.
Ограничение привилегий расширений ограничивает возможности потенциального злоумышленника.
XMLHttpRequest из перекрестного источника
Расширение может использовать XMLHttpRequest только для получения ресурсов от себя и от доменов, указанных в разрешениях.
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"permissions": [
"/*",
"https://*.google.com/"
],
"manifest_version": 2
}
Это расширение запрашивает доступ ко всему на сайте Developer.chrome.com и поддоменам Google, указав в разрешениях "/*"
и "https://*google.com/"
. Если бы расширение было скомпрометировано, оно все равно имело бы разрешение на взаимодействие только с веб-сайтами, которые соответствуют шаблону соответствия . Злоумышленник не сможет получить доступ к "https://user_bank_info.com"
или взаимодействовать с "https://malicious_website.com"
.
Ограничить поля манифеста
Включение ненужных регистраций в манифест создает уязвимости и делает расширение более заметным. Ограничьте поля манифеста теми, от которых зависит расширение, и обеспечьте регистрацию определенных полей.
Внешнее подключение
Используйте поле externally_connectable
, чтобы объявить, с какими внешними расширениями и веб-страницами расширение будет обмениваться информацией. Ограничьте круг лиц, с которыми расширение может подключаться извне, доверенными источниками.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"/*",
"https://*google.com/"
],
"accepts_tls_channel_id": false
},
...
}
Доступные через Интернет ресурсы
Если сделать ресурсы доступными через Интернет, в разделе web_accessible_resources
расширение будет обнаружено веб-сайтами и злоумышленниками.
{
...
"web_accessible_resources": [
"images/*.png",
"style/secure_extension.css",
"script/secure_extension.js"
],
...
}
Чем больше доступных веб-ресурсов, тем больше возможностей может использовать потенциальный злоумышленник. Сведите эти файлы к минимуму.
Включите явную политику безопасности контента.
Включите в манифест политику безопасности контента для расширения, чтобы предотвратить атаки с использованием межсайтовых сценариев. Если расширение загружает ресурсы только от себя, пропишите следующее:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": "default-src 'self'"
"manifest_version": 2
}
Если в расширении необходимо включить скрипты с определенных хостов, их можно включить:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": "default-src 'self' https://extension.resource.com"
"manifest_version": 2
}
Избегайте исполняемых API
API, выполняющие код, следует заменить более безопасными альтернативами.
document.write() и внутреннийHTML
Хотя динамически создавать HTML-элементы с помощью document.write()
и innerHTML
может быть проще, это оставляет расширение и веб-страницы, от которых зависит расширение, открытыми для злоумышленников, вставляющих вредоносные сценарии. Вместо этого вручную создайте узлы DOM и используйте innerText
для вставки динамического контента.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
оценка()
По возможности избегайте использования eval()
, чтобы предотвратить атаки, поскольку eval()
выполнит любой переданный в него код, который может быть вредоносным.
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();
Вместо этого отдайте предпочтение более безопасным и быстрым методам, таким как JSON.parse()
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();
Используйте сценарии контента осторожно
Хотя контент-скрипты живут в изолированном мире , они не застрахованы от атак:
- Скрипты контента — единственная часть расширения, которая напрямую взаимодействует с веб-страницей. Из-за этого враждебные веб-страницы могут манипулировать частями DOM, от которых зависит сценарий содержимого, или использовать неожиданное поведение веб-стандартов, например именованные элементы .
- Для взаимодействия с DOM веб-страниц сценарии контента должны выполняться в том же процессе рендеринга, что и веб-страница. Это делает сценарии контента уязвимыми для утечки данных через атаки по побочным каналам (например, Spectre ), а также для захвата злоумышленником, если вредоносная веб-страница ставит под угрозу процесс рендеринга.
Конфиденциальная работа должна выполняться в выделенном процессе, например в фоновом сценарии расширения. Избегайте случайного раскрытия привилегий расширения сценариям содержимого:
- Предположим, что сообщения из сценария содержимого могли быть созданы злоумышленником (например, проверить и очистить все входные данные и защитить ваши сценарии от межсайтового сценария ).
- Предположим, что любые данные, отправленные в сценарий содержимого, могут попасть на веб-страницу. Не отправляйте конфиденциальные данные (например, секреты расширения, данные из других веб-источников, историю просмотров) в сценарии контента.
- Ограничьте объем привилегированных действий, которые могут быть инициированы сценариями содержимого. Не разрешайте сценариям контента инициировать запросы к произвольным URL-адресам или передавать произвольные аргументы API расширений (например, не разрешайте передавать произвольные URL-адреса для
fetch
или APIchrome.tabs.create
).
Регистрация и дезинфекция входных данных
Защитите расширение от вредоносных сценариев, ограничив прослушиватели только тем, что ожидает расширение, проверив отправителей входящих данных и очистив все входные данные.
Расширение должно регистрироваться для runtime.onRequestExternal
только в том случае, если оно ожидает связи с внешним веб-сайтом или расширением. Всегда проверяйте, соответствует ли отправитель надежному источнику.
// 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.");
});
Не позволяйте расширению выполнять сценарий злоумышленника, выполняя очистку вводимых пользователем данных и входящих данных, даже из самого расширения и из утвержденных источников. Избегайте исполняемых API .
function sanitizeInput(input) {
return input.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
}