Luôn an toàn

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 của những kẻ tấn công. Nếu một tiện ích bị xâm phạm, mọi người dùng sử dụng tiện ích đó đều dễ bị tấn công xâm nhập độc hại và không mong muốn. Giữ an toàn cho tiện ích và bảo vệ người dùng tiện ích bằng cách kết hợp các 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 thông tin về là bị xâm phạm, kẻ tấn công có thể đẩy mã độc hại trực tiếp đến tất cả người dùng. Hãy bảo vệ các tài khoản này bằng cách tạo tài khoản nhà phát triển cụ thể và bật tính năng xác thực hai yếu tố , tốt nhất là bằng khoá bảo mật .

Duy trì tính chọn lọc cho các nhóm

Nếu bạn sử dụng tính năng xuất bản nhóm, hãy đảm bảo nhóm chỉ bao gồm các nhà phát triển đáng tin cậy. Không chấp nhận yêu cầu đăng ký thành viên từ người không xác định.

Không bao giờ sử dụng HTTP

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 có trình nghe trộm hoặc có chứa nội dung sửa đổi. HTTPS luôn được ưu tiên vì nó được tích hợp sẵn bảo mật tránh 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 đối với các đặc quyền đã được yêu cầu rõ ràng trong tệp kê khai. Tiện ích phải giảm thiểu quyền của mình bằng cách chỉ đăng ký API và các trang web mà họ phụ thuộc. Bạn nên giữ mã tuỳ ý ở mức tối thiểu.

Việc giới hạn đặc quyền đối với 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 nhiều nguồn gốc

Một tiện ích chỉ có thể sử dụng XMLHttpRequest để nhận 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 bất kỳ nội dung nào trên developer.chrome.com và các miền con của Google bằng cách liệt kê "/*""https://*google.com/" trong quyền truy cập. Nếu tiện ích mở rộng đã bị xâm nhập, tiện ích này vẫn chỉ có quyền tương tác với các trang web đáp ứng mẫu 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 lượt đăng ký không cần thiết vào tệp kê khai sẽ tạo ra lỗ hổng bảo mật và tạo tiện ích rõ ràng hơn. Giới hạn các trường tệp kê khai ở những trường mà tiện ích dựa vào và cung cấp trường cụ thể của bạn.

Có thể kết nối bên ngoài

Sử dụng trường externally_connectable để khai báo tiện ích bên ngoài và trang web nào mà sẽ trao đổi thông tin với. Giới hạn những người mà tiện ích có thể kết nối bên ngoài nguồn đáng tin cậy.

{
  "name": "Super Safe Extension",
  "externally_connectable": {
    "ids": [
      "iamafriendlyextensionhereisdatas"
    ],
    "matches": [
      "/*",
      "https://*google.com/"
    ],
    "accepts_tls_channel_id": false
  },
  ...
}

Các tài nguyên có thể truy cập trên web

Cung cấp tài nguyên cho mọi người trên web, trong web_accessible_resources sẽ tạo tiện ích bổ sung có thể bị các trang web và kẻ tấn công phát hiện.

{
  ...
  "web_accessible_resources": [
    "images/*.png",
    "style/secure_extension.css",
    "script/secure_extension.js"
  ],
  ...
}

Càng có nhiều tài nguyên trên web, kẻ tấn công tiềm ẩn càng có nhiều cách thức khai thác. Giữ lại tối thiểu các tệp này.

Đưa vào chính sách bảo mật nội dung phản cảm

Đưa chính sách bảo mật nội dung vào tiện ích vào tệp kê khai để ngăn tình trạng chéo trang web tập lệnh. Nếu tiện ích chỉ tải tài nguyên từ chính tiện ích đó, 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 bao gồm các tập lệnh từ các máy chủ cụ thể, thì bạn có thể đưa các tập lệnh đó vào:

{
  "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 các API có thể thực thi

Các API thực thi mã nên được thay thế bằng các API thay thế an toàn hơn.

document.write() và innerHTML

Mặc dù việc tạo các phần tử HTML một cách linh động bằng document.write()innerHTML có thể sẽ đơn giản hơn, tiện ích đó sẽ rời khỏi tiện ích, còn các trang web mà tiện ích đó dựa vào sẽ bị kẻ tấn công xâm nhập các 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à sử 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 tệp đó vì có thể gây hại.

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

Cẩn trọng khi sử dụng kịch bản nội dung

Mặc dù tập lệnh nội dung được xây dựng trong một thế giới tách biệt, nhưng chúng sẽ không tránh được 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 thù địch có thể thao túng các phần của DOM mà tập lệnh nội dung phụ thuộc, hoặc khai thác hành vi tiêu chuẩn web đáng ngạc nhiên, chẳng hạn như 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 đồ hoạ như trang web. Điều này khiến 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 bên (ví dụ: Spectre) và bị kẻ tấn công chiếm đoạt nếu một trang web độc hại xâm phạm quá trình kết xuất đồ hoạ.

Công việc nhạy cảm phải được thực hiện trong một quy trình riêng, chẳng hạn như nền của tiện ích tập lệnh. Tránh việc vô tình để lộ đặc quyền của tiện ích cho các tập lệnh nội dung:

  • Giả sử rằng thư từ tập lệnh nội dung có thể đã bị kẻ tấn công tạo (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 khỏi 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 đều có thể bị rò rỉ ra trang web. Không gửi dữ liệu nhạy cảm (ví dụ: bí mật từ tiện ích, dữ liệu từ các nguồn web khác, nhật ký duyệt web) đối với nội dung các tập lệnh.
  • Giới hạn phạm vi của các thao tác đặc quyền mà tập lệnh nội dung có thể kích hoạt. Không cho phép các tập lệnh nội dung để kích hoạt yêu cầu đến các URL tuỳ ý hoặc truyền đối số tuỳ ý đến các API tiện ích (ví dụ: không cho phép truyền URL tuỳ ý đến fetch hoặc chrome.tabs.create).

Đăng ký và dọn dẹp dữ liệu đầ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ỉ ở nội dung của tiện ích mong đợi, xác thực trình gửi dữ liệu đến và dọn dẹp tất cả dữ liệu đầu vào.

Một tiện ích chỉ nên đăng ký cho runtime.onRequestExternal, nếu đang dự kiến từ một trang web hoặc tiện ích bên ngoài. Luôn xác thực rằng người gửi khớp với 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ả thông báo qua sự kiện runtime.onMessage từ chính tiện ích cũng cần được xem xét kỹ để đảm bảo MessageSender không đến từ một tập lệnh nội dung bị xâm phạm.

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.allowedAction)
    console.log("This is an allowed action.");
});

Ngăn không cho tiện ích thực thi tập lệnh của kẻ tấn công bằng cách dọn dẹp dữ liệu đầu vào của người dùng và thư đến dữ liệu, ngay cả từ chính tiện ích và các nguồn được phê duyệt. Tránh các API có thể thực thi.

function sanitizeInput(input) {
    return input.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
}