Các tiện ích có quyền truy cập vào các đặc quyền đặc biệt trong trình duyệt, khiến chúng trở thành mục tiêu hấp dẫn đối với kẻ tấn công. Nếu một tiện ích bị xâm nhập, mọi người dùng tiện ích đó đều có nguy cơ bị xâm nhập trái phép và không mong muốn. Bảo mật tiện ích và bảo vệ người dùng bằng cách áp dụng những phương pháp này.
Bảo vệ tài khoản nhà phát triển
Mã tiện ích được tải lên và cập nhật thông qua Tài khoản Google. Nếu tài khoản của nhà phát triển bị xâm nhập, kẻ tấn công có thể đẩy mã độc trực tiếp đến tất cả người dùng. Bảo vệ các tài khoản này bằng cách tạo riêng tài khoản nhà phát triển và bật tính năng xác thực hai yếu tố , tốt nhất là dùng khoá bảo mật .
Giữ lại các nhóm này
Nếu sử dụng tính năng xuất bản theo nhóm, hãy giới hạn nhóm chỉ bao gồm những nhà phát triển đáng tin cậy. Không chấp nhận yêu cầu tham gia của người lạ.
Không bao giờ sử dụng HTTP, Ever
Khi yêu cầu hoặc gửi dữ liệu, hãy tránh kết nối HTTP. Giả sử rằng mọi kết nối HTTP đều có người nghe lén hoặc chứa nội dung sửa đổi. Bạn nên luôn ưu tiên HTTPS vì giao thức này có tính năng bảo mật tích hợp giúp ngăn chặn hầu hết các cuộc tấn công xen giữa.
Yêu cầu cấp quyền tối thiểu
Trình duyệt Chrome giới hạn quyền truy cập của tiện ích vào những đặc quyền đã được yêu cầu rõ ràng trong tệp kê khai. Tiện ích nên giảm thiểu các quyền bằng cách chỉ đăng ký những API và trang web mà chúng phụ thuộc vào. Bạn nên hạn chế tối đa mã tuỳ ý.
Việc hạn chế các đặc quyền của tiện ích sẽ hạn chế những gì mà kẻ tấn công tiềm ẩn có thể khai thác.
XMLHttpRequest trên nhiều nguồn gốc
Tiện ích chỉ có thể sử dụng XMLHttpRequest để lấy tài nguyên từ chính tiện ích và từ các miền được chỉ định trong quyền.
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"permissions": [
"/*",
"https://*.google.com/"
],
"manifest_version": 2
}
Tiện ích này yêu cầu quyền truy cập vào mọi nội dung trên developer.chrome.com và các miền con của Google bằng cách liệt kê "/*" và "https://*google.com/" trong phần quyền. Nếu tiện ích này bị xâm nhập, thì tiện ích đó vẫn chỉ có quyền tương tác với những trang web đáp ứng mẫu so khớp. Kẻ tấn công sẽ không thể truy cập vào "https://user_bank_info.com" hoặc tương tác với "https://malicious_website.com".
Giới hạn các trường trong tệp kê khai
Việc đưa các mục đăng ký không cần thiết vào tệp kê khai sẽ tạo ra các lỗ hổng và khiến tiện ích trở nên dễ thấy hơn. Giới hạn các trường tệp kê khai đối với những trường mà tiện ích dựa vào và cung cấp thông tin đăng ký trường cụ thể.
Có thể kết nối với bên ngoài
Sử dụng trường externally_connectable để khai báo những tiện ích bên ngoài và trang web mà tiện ích sẽ trao đổi thông tin. Hạn chế những người mà tiện ích có thể kết nối bên ngoài với các nguồn đáng tin cậy.
{
"name": "Super Safe Extension",
"externally_connectable": {
"ids": [
"iamafriendlyextensionhereisdatas"
],
"matches": [
"/*",
"https://*google.com/"
],
"accepts_tls_channel_id": false
},
...
}
Tài nguyên có thể truy cập trên web
Việc cung cấp tài nguyên có thể truy cập bằng web, trong web_accessible_resources sẽ giúp các trang web và kẻ tấn công phát hiện được tiện ích.
{
...
"web_accessible_resources": [
"images/*.png",
"style/secure_extension.css",
"script/secure_extension.js"
],
...
}
Càng có nhiều tài nguyên có thể truy cập trên web, kẻ tấn công tiềm ẩn càng có nhiều cách để khai thác. Hạn chế tối đa số lượng tệp này.
Đưa ra một chính sách bảo mật nội dung rõ ràng
Thêm một chính sách bảo mật nội dung cho tiện ích trong tệp kê khai để ngăn chặn các cuộc tấn công bằng tập lệnh trên nhiều trang web. Nếu tiện ích chỉ tải tài nguyên từ chính nó, hãy đăng ký như sau:
{
"name": "Very Secure Extension",
"version": "1.0",
"description": "Example of a Secure Extension",
"content_security_policy": "default-src 'self'"
"manifest_version": 2
}
Nếu tiện ích cần có các tập lệnh từ những máy chủ lưu trữ cụ thể, thì bạn có thể thêm các tập lệnh đó:
{
"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
}
Tránh dùng các API có thể thực thi
Bạn nên thay thế các API thực thi mã bằng những lựa chọn thay thế an toàn hơn.
document.write() và innerHTML
Mặc dù có thể đơn giản hơn khi tạo các phần tử HTML một cách linh động bằng document.write() và innerHTML, nhưng điều này khiến tiện ích và các trang web mà tiện ích phụ thuộc vào có nguy cơ bị kẻ tấn công chèn tập lệnh độc hại. Thay vào đó, hãy tạo các nút DOM theo cách thủ công và dùng innerText để chèn nội dung động.
function constructDOM() {
let newTitle = document.createElement('h1');
newTitle.innerText = host;
document.appendChild(newTitle);
}
eval()
Tránh sử dụng eval() bất cứ khi nào có thể để ngăn chặn các cuộc tấn công, vì eval() sẽ thực thi mọi mã được truyền vào đó, có thể là mã độc.
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();
Thay vào đó, hãy ưu tiên các phương thức an toàn và nhanh hơn, chẳng hạn như 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();
Hãy thận trọng khi sử dụng tập lệnh nội dung
Mặc dù tập lệnh nội dung nằm trong một thế giới biệt lập, nhưng chúng không miễn nhiễm với các cuộc tấn công:
- Tập lệnh nội dung là phần duy nhất của tiện ích tương tác trực tiếp với trang web. Do đó, các trang web độc hại có thể thao túng các phần của DOM mà tập lệnh nội dung phụ thuộc vào hoặc khai thác hành vi bất ngờ của tiêu chuẩn web, chẳng hạn như các mục được đặt tên.
- Để tương tác với DOM của các trang web, tập lệnh nội dung cần thực thi trong cùng một quy trình kết xuất như trang web. Điều này khiến các tập lệnh nội dung dễ bị rò rỉ dữ liệu thông qua các cuộc tấn công kênh phụ (ví dụ: Spectre) và dễ bị kẻ tấn công chiếm đoạt nếu một trang web độc hại xâm nhập vào quy trình kết xuất.
Bạn nên thực hiện các thao tác nhạy cảm trong một quy trình chuyên biệt, chẳng hạn như tập lệnh nền của tiện ích. Tránh vô tình để lộ các đặc quyền của tiện ích cho tập lệnh nội dung:
- Giả sử rằng các thông báo từ một tập lệnh nội dung có thể do kẻ tấn công tạo ra (ví dụ: xác thực và dọn dẹp tất cả dữ liệu đầu vào và bảo vệ tập lệnh của bạn khỏi tấn công tập lệnh trên nhiều trang web).
- Giả sử mọi dữ liệu được gửi đến tập lệnh nội dung có thể bị rò rỉ sang trang web. Không gửi dữ liệu nhạy cảm (ví dụ: các khoá bí mật từ tiện ích, dữ liệu từ các nguồn gốc web khác, nhật ký duyệt web) đến tập lệnh nội dung.
- Giới hạn phạm vi của các hành động đặc quyền mà tập lệnh nội dung có thể kích hoạt. Không cho phép tập lệnh nội dung kích hoạt các yêu cầu đến URL tuỳ ý hoặc truyền các đối số tuỳ ý đến API tiện ích (ví dụ: không cho phép truyền URL tuỳ ý đến API
fetchhoặcchrome.tabs.create).
Đăng ký và làm sạch thông tin đầu vào
Bảo vệ tiện ích khỏi các tập lệnh độc hại bằng cách giới hạn trình nghe chỉ ở những gì tiện ích mong đợi, xác thực người gửi dữ liệu đến và dọn dẹp tất cả dữ liệu đầu vào.
Tiện ích chỉ nên đăng ký runtime.onRequestExternal nếu đang chờ thông tin liên lạc từ một trang web hoặc tiện ích bên ngoài. Luôn xác thực để đảm bảo người gửi khớp với một nguồn đáng tin cậy.
// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (sender.id === kFriendlyExtensionId)
doSomething();
});
Ngay cả các thông báo thông qua sự kiện runtime.onMessage từ chính tiện ích cũng cần được xem xét kỹ lưỡng để đảm bảo MessageSender không phải từ một tập lệnh nội dung bị xâm nhập.
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.allowedAction)
console.log("This is an allowed action.");
});
Ngăn tiện ích thực thi tập lệnh của kẻ tấn công bằng cách làm sạch dữ liệu đầu vào của người dùng và dữ liệu đến, ngay cả từ chính tiện ích và các nguồn được phê duyệt. Tránh dùng các API có thể thực thi.
function sanitizeInput(input) {
return input.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
}