Tách biệt trang web cho nhà phát triển web

Chrome 67 trên máy tính có một tính năng mới tên là Cách ly trang web được bật theo mặc định. Chiến dịch này bài viết giải thích về tính năng Tách biệt trang web, tại sao tính năng này lại cần thiết và lý do nhà phát triển web nên hãy chú ý đến điều đó.

Cách ly trang web là gì?

Internet là để xem video về mèo và quản lý ví tiền mã hoá, cùng nhiều hoạt động khác — nhưng bạn không muốn fluffycats.example có quyền truy cập vào các đồng tiền mã hoá quý giá của bạn! Thật may mắn, các trang web thường không thể truy cập vào dữ liệu của nhau trong trình duyệt nhờ cùng một nguồn gốc Chính sách. Tuy nhiên, các trang web độc hại có thể tìm cách bỏ qua chính sách này để tấn công các trang web khác và đôi khi, sẽ có lỗi bảo mật trong mã trình duyệt thực thi Chính sách cùng nguồn gốc. Chiến lược phát hành đĩa đơn Nhóm Chrome hướng đến việc khắc phục các lỗi như vậy nhanh nhất có thể.

Cách ly trang web là một tính năng bảo mật trong Chrome, tạo thêm một hàng phòng vệ để đảm bảo ít khả năng thành công hơn. Mã này đảm bảo rằng các trang từ các trang web khác nhau luôn được đặt thành các quy trình khác nhau, mỗi quy trình chạy trong một hộp cát giới hạn những gì quy trình được phép thực hiện. Việc này cũng chặn không cho quá trình này nhận một số loại dữ liệu nhạy cảm nhất định từ các trang web khác. Là một kết quả là với tính năng Cách ly trang web, một trang web độc hại sẽ gặp khó khăn hơn nhiều khi sử dụng dữ liệu suy đoán tấn công kênh bên như Spectre để lấy cắp dữ liệu từ các trang web khác. Khi nhóm Chrome hoàn tất các biện pháp thực thi bổ sung, Cách ly trang web cũng sẽ giúp ích ngay cả khi trang của kẻ tấn công có thể phá vỡ một số của các quy tắc theo quy trình riêng.

Việc tách biệt trang web giúp các trang web không đáng tin cậy khó truy cập hoặc lấy cắp thông tin hơn một cách hiệu quả từ tài khoản của bạn trên các trang web khác. Điều này giúp tăng cường khả năng bảo vệ trước nhiều loại lỗi bảo mật, chẳng hạn như cuộc tấn công kênh bên của Meltdown và Spectre gần đây.

Để biết thêm thông tin chi tiết về tính năng Cách ly trang web, hãy xem bài viết của chúng tôi trên blog về bảo mật của Google.

Chặn đọc trên nhiều nguồn gốc

Ngay cả khi tất cả các trang trên nhiều trang web được đưa vào những quy trình riêng biệt, các trang vẫn có thể yêu cầu một cách hợp pháp một số tài nguyên phụ trên nhiều trang web, chẳng hạn như hình ảnh và JavaScript. Trang web độc hại có thể sử dụng Phần tử <img> để tải tệp JSON chứa dữ liệu nhạy cảm, chẳng hạn như số dư ngân hàng:

<img src="https://your-bank.example/balance.json" />
<!-- Note: the attacker refused to add an `alt` attribute, for extra evil points. -->

Khi không có tính năng Tách biệt trang web, nội dung của tệp JSON sẽ chuyển vào bộ nhớ của trình kết xuất quá trình xử lý, tại thời điểm đó trình kết xuất nhận thấy rằng đó không phải là định dạng hình ảnh hợp lệ và không hiển thị một hình ảnh. Tuy nhiên, kẻ tấn công có thể khai thác lỗ hổng bảo mật như Spectre để đọc phần bộ nhớ.

Thay vì sử dụng <img>, kẻ tấn công cũng có thể sử dụng <script> để cam kết dữ liệu nhạy cảm với bộ nhớ:

<script src="https://your-bank.example/balance.json"></script>

Chặn đọc trên nhiều nguồn gốc (CORB) là một tính năng bảo mật mới ngăn chặn nội dung của balance.json không bao giờ đi vào bộ nhớ của bộ nhớ xử lý kết xuất đồ hoạ dựa trên loại MIME của bộ nhớ đó.

Hãy cùng phân tích cách hoạt động của CORB. Một trang web có thể yêu cầu hai loại tài nguyên từ máy chủ:

  1. tài nguyên dữ liệu chẳng hạn như tài liệu HTML, XML hoặc JSON
  2. tài nguyên nội dung nghe nhìn như hình ảnh, JavaScript, CSS hoặc phông chữ

Một trang web có thể nhận tài nguyên dữ liệu từ nguồn gốc của chính trang web đó hoặc từ các nguồn gốc khác thông qua tiêu đề CORS không bắt buộc, chẳng hạn như Access-Control-Allow-Origin: *. Mặt khác, tài nguyên truyền thông có thể được đưa vào từ bất kỳ nguồn gốc của bạn, ngay cả khi không có các tiêu đề CORS được phép.

CORB ngăn quá trình kết xuất nhận tài nguyên dữ liệu trên nhiều nguồn gốc (ví dụ: HTML, XML hoặc JSON) nếu:

  • tài nguyên có tiêu đề X-Content-Type-Options: nosniff
  • CORS không cho phép truy cập vào tài nguyên một cách rõ ràng

Nếu tài nguyên dữ liệu trên nhiều nguồn gốc chưa đặt tiêu đề X-Content-Type-Options: nosniff, CORB cố gắng phân tích nội dung phản hồi để xác định xem đó là HTML, XML hay JSON. Đây là vì một số máy chủ web bị định cấu hình sai và phân phát hình ảnh dưới dạng text/html chẳng hạn.

Tài nguyên dữ liệu bị chặn bởi chính sách CORB hiển thị trong quy trình dưới dạng trống, mặc dù yêu cầu vẫn diễn ra trong nền. Do đó, trang web độc hại sẽ gặp khó khăn kéo dữ liệu qua nhiều trang web vào quy trình đánh cắp.

Để được bảo mật tối ưu và nhận được lợi ích từ CORB, bạn nên thực hiện những việc sau:

  • Hãy đánh dấu các câu trả lời có tiêu đề Content-Type chính xác. (Ví dụ: tài nguyên HTML nên là được phân phát dưới dạng text/html, tài nguyên JSON với loại MIME JSON và các tài nguyên XML có loại MIME XML).
  • Chọn không sử dụng tính năng theo dõi bằng cách sử dụng tiêu đề X-Content-Type-Options: nosniff. Nếu không có tiêu đề này, Chrome sẽ phân tích nhanh nội dung để cố xác nhận xem loại nội dung đó là chính xác hay chưa, nhưng vì đây chọn cho phép phản hồi để tránh chặn những tệp như tệp JavaScript, tốt hơn là bạn nên tự khẳng định rằng mình đang làm điều đúng đắn.

Để biết thêm thông tin, hãy tham khảo Bài viết về CORB dành cho nhà phát triển web hoặc nội dung giải thích chuyên sâu của chúng tôi về CORB.

Tại sao các nhà phát triển web nên quan tâm đến tính năng Tách biệt trang web?

Đối với hầu hết các tính năng, Tách biệt trang web là một tính năng trình duyệt ngầm không trực tiếp được sử dụng cho nhà phát triển web. Ví dụ: không có API hiển thị trên web mới nào để tìm hiểu. Nhìn chung, web các trang không thể phân biệt khi chạy có hoặc không có tính năng Tách biệt trang web.

Tuy nhiên, có một số ngoại lệ đối với quy tắc này. Khi bật tính năng Cách ly trang web, bạn cần lưu ý một vài có thể ảnh hưởng đến trang web của bạn. Chúng tôi duy trì danh sách các vấn đề đã biết về việc cô lập trang web, và chúng tôi giải thích chi tiết về những điều quan trọng nhất dưới đây.

Bố cục toàn trang không còn đồng bộ

Với tính năng Tách biệt trang web, bố cục toàn trang không còn được đảm bảo là đồng bộ, vì các khung của một trang hiện có thể được trải rộng qua nhiều quá trình. Điều này có thể ảnh hưởng đến các trang nếu chúng giả định rằng thì thay đổi bố cục sẽ ngay lập tức áp dụng cho tất cả các khung trên trang.

Ví dụ: hãy xem xét một trang web có tên fluffykittens.example giao tiếp với tiện ích mạng xã hội được lưu trữ trên social-widget.example:

<!-- https://fluffykittens.example/ -->
<iframe src="https://social-widget.example/" width="123"></iframe>
<script>
  const iframe = document.querySelector('iframe');
  iframe.width = 456;
  iframe.contentWindow.postMessage(
    // The message to send:
    'Meow!',
    // The target origin:
    'https://social-widget.example'
  );
</script>

Ban đầu, chiều rộng của <iframe> của tiện ích mạng xã hội là 123 pixel. Nhưng sau đó, trang FluffyKittens thay đổi chiều rộng thành 456 pixel (kích hoạt bố cục) và gửi thông báo tới tiện ích mạng xã hội, chứa đoạn mã sau:

<!-- https://social-widget.example/ -->
<script>
  self.onmessage = () => {
    console.log(document.documentElement.clientWidth);
  };
</script>

Mỗi khi nhận được một tin nhắn thông qua API postMessage, tiện ích mạng xã hội sẽ ghi lại chiều rộng của phần tử <html> gốc.

Giá trị chiều rộng nào được ghi nhật ký? Trước khi Chrome bật tính năng Tách biệt trang web, câu trả lời là 456. Truy cập document.documentElement.clientWidth buộc bố cục, vốn thường là đồng bộ trước Chrome đã bật Tách biệt trang web. Tuy nhiên, khi bạn bật tính năng Cách ly trang web, tiện ích mạng xã hội trên nhiều nguồn gốc bố cục lại hiện diễn ra không đồng bộ trong một quy trình riêng. Do vậy, giờ đây, câu trả lời cũng có thể là 123, tức là giá trị width cũ.

Nếu một trang thay đổi kích thước của một <iframe> trên nhiều nguồn gốc, sau đó gửi một postMessage đến trang đó kèm theo Khung nhận tách biệt trang web có thể chưa biết kích thước mới của khung nhận khi nhận được thông báo. Xem thêm nói chung, điều này có thể phá vỡ trang nếu chúng cho rằng thay đổi bố cục ngay lập tức áp dụng cho khung trên trang.

Trong ví dụ cụ thể này, một giải pháp mạnh mẽ hơn sẽ đặt width trong khung mẹ, và phát hiện thay đổi đó trong <iframe> bằng cách theo dõi sự kiện resize.

Trình xử lý huỷ tải có thể hết thời gian chờ thường xuyên hơn

Khi một khung điều hướng hoặc đóng, tài liệu cũ cũng như mọi tài liệu khung phụ được nhúng trong đó đều chạy trình xử lý unload. Nếu thao tác điều hướng mới xảy ra trong cùng một quy trình kết xuất (ví dụ: cho điều hướng cùng nguồn gốc), các trình xử lý unload của tài liệu cũ và các khung con của tài liệu cũ có thể chạy cho một khoảng thời gian dài tuỳ ý trước khi cho phép xác nhận thành phần điều hướng mới.

addEventListener('unload', () => {
  doSomethingThatMightTakeALongTime();
});

Trong trường hợp này, trình xử lý unload trong tất cả khung hình đều rất đáng tin cậy.

Tuy nhiên, ngay cả khi không có tính năng Tách biệt trang web, một số thao tác điều hướng khung chính vẫn diễn ra qua nhiều quá trình, do đó ảnh hưởng đến huỷ tải hành vi của trình xử lý. Ví dụ: nếu bạn điều hướng từ old.example đến new.example bằng cách nhập URL trong thanh địa chỉ, quá trình điều hướng new.example sẽ diễn ra trong một quy trình mới. Huỷ tải trình xử lý cho old.example và các khung phụ của nó chạy trong quy trình old.example ở chế độ nền, sau khi trang new.example được hiển thị và các trình xử lý huỷ tải cũ sẽ bị chấm dứt nếu không kết thúc trong một khoảng thời gian chờ nhất định. Do trình xử lý huỷ tải có thể không hoàn tất trước thời gian chờ, hành vi gỡ tải ít đáng tin cậy hơn.

Với tính năng Cách ly trang web, mọi thao tác điều hướng trên nhiều trang web đều diễn ra trên nhiều trang web để tài liệu các trang web khác nhau không chia sẻ quy trình với nhau. Do đó, trường hợp trên áp dụng trong nhiều trường hợp hơn và việc huỷ tải trình xử lý trong <iframe> thường có hành vi chạy ở chế độ nền và hết thời gian chờ được mô tả ở trên.

Một điểm khác biệt khác của quá trình Cách ly trang web là thứ tự song song mới của các trình xử lý huỷ tải: khi không có tính năng Cách ly trang web, các trình xử lý huỷ tải sẽ chạy theo thứ tự từ trên xuống nghiêm ngặt trên các khung hình. Nhưng với trang web Việc tách biệt, huỷ tải chạy song song trên nhiều quy trình.

Đây là những hệ quả cơ bản của việc bật tính năng Cô lập trang web. Nhóm Chrome đang nỗ lực nghiên cứu cải thiện độ tin cậy của trình xử lý huỷ tải cho các trường hợp sử dụng phổ biến (nếu có thể). Chúng tôi cũng phát hiện các lỗi trong đó trình xử lý tải khung phụ chưa thể sử dụng một số tính năng và đang tìm cách giải quyết chúng.

Một trường hợp quan trọng đối với trình xử lý huỷ tải là gửi ping cuối phiên. Việc này thường được thực hiện như sau: sau:

addEventListener('pagehide', () => {
  const image = new Image();
  img.src = '/end-of-session';
});

Do sự thay đổi này, một phương pháp hiệu quả hơn và hiệu quả hơn là sử dụng navigator.sendBeacon thay vào đó:

addEventListener('pagehide', () => {
  navigator.sendBeacon('/end-of-session');
});

Nếu cần có nhiều quyền kiểm soát hơn đối với yêu cầu, bạn có thể sử dụng lựa chọn keepalive của API Tìm nạp:

addEventListener('pagehide', () => {
  fetch('/end-of-session', {keepalive: true});
});

Kết luận

Cách ly trang web khiến các trang web không đáng tin cậy khó truy cập hoặc lấy cắp thông tin từ trên các trang web khác bằng cách tách riêng từng trang web thành một quy trình riêng. Để làm được điều đó, CORB cố gắng loại bỏ tài nguyên dữ liệu nhạy cảm khỏi quá trình kết xuất đồ hoạ. Những đề xuất trên của chúng tôi giúp đảm bảo bạn khai thác tối đa các tính năng bảo mật mới này.

Nhờ vào Alex Moshchuk, Charlie Reis, Jason Miller, Nasko Oskov, Philip Walton, Shubhie Panicker và Thomas Steiner để đọc phiên bản nháp của bài viết này và đưa ra ý kiến phản hồi.