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 của kẻ tấn công. Nếu một tiện ích bị xâm phạm, mọi người dùng tiện ích đó đều dễ bị 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 của 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 tài khoản của nhà phát triển bị xâm phạm, kẻ tấn công có thể đẩy mã độc trực tiếp cho tất cả người dùng. Bảo vệ những 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à bằng một khoá bảo mật .

Duy trì lựa chọn của các nhóm

Nếu sử dụng tính năng xuất bản nhóm, hãy giới hạn nhóm chỉ 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ý làm thành viên từ những 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 sử dụng kết nối HTTP. Giả sử rằng bất kỳ kết nối HTTP nào cũng sẽ bị nghe trộm hoặc chứa các 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 sẵn, giúp tránh được hầu hết các cuộc tấn công xen giữa.

Yêu cầu quyền tối thiểu

Trình duyệt Chrome giới hạn quyền truy cập của một tiện ích vào các đặc quyền đã được yêu cầu rõ ràng trong tệp kê khai. Các tiện ích nên giảm thiểu quyền truy cập bằng cách chỉ đăng ký các API và trang web mà chúng phụ thuộc. Bạn nên duy trì mã tuỳ ý ở mức tối thiểu.

Việc giới hạn đặc quyền của một tiện ích sẽ hạn chế những gì mà kẻ tấn công tiềm năng có thể khai thác.

XMLHttpRequest trên 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 nó và từ những miền được chỉ định trong các 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ê "/*""https://*google.com/" trong các quyền. Nếu bị xâm phạm, tiện ích đó vẫn chỉ có quyền tương tác với các 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 yêu cầu đăng ký không cần thiết vào tệp kê khai sẽ tạo ra lỗ hổng và khiến tiện ích dễ nhìn thấy hơn. Giới hạn các trường tệp kê khai ở những trường mà tiện ích sẽ dựa vào và đăng ký các 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 trang web và tiện ích bên ngoài 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

Trong web_accessible_resources, để các tài nguyên có thể truy cập được trên web sẽ giúp các trang web và kẻ tấn công có thể phát hiện thấy một 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 càng có thể khai thác nhiều cách khác. Hãy giữ cho các tệp này ở mức tối thiểu.

Cung cấp chính sách bảo mật nội dung phản cảm

Thêm 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 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ững nội dung 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 tập lệnh từ máy chủ cụ thể, thì bạn có thể bao gồ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 các API thực thi

Bạn nên thay thế các API thực thi mã bằng các phương án thay thế an toàn hơn.

document.write() và innerHTML

Mặc dù việc tự động tạo các phần tử HTML bằng document.write()innerHTML có thể đơn giản hơn, nhưng phương thức này sẽ rời khỏi tiện ích và các trang web mà tiện ích đó phụ thuộc sẽ có thể mở để 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à 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 đó, có thể là mã độc 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 tập lệnh nội dung

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

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

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

Đăng ký và dọn dẹp đầu vào

Bảo vệ tiện ích khỏi các tập lệnh độc hại bằng cách chỉ giới hạn trình nghe ở nội dung 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 dự kiến kết nối 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 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();
});

Bạn cũng phải xem xét kỹ lưỡng cả các tin nhắn qua sự kiện runtime.onMessage từ chính tiện ích để đảm bảo MessageSender không thuộc 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 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à dữ liệu đến, 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;');
}