Ngày xuất bản: 4 tháng 5 năm 2020
Trong bài viết Đưa trang web của bạn vào trạng thái "tách biệt nhiều nguồn gốc" bằng COOP và COEP, chúng tôi đã giải thích cách chuyển sang trạng thái "tách biệt nhiều nguồn gốc" bằng COOP và COEP. Đây là bài viết bổ sung giải thích lý do cần có chế độ tách biệt nhiều nguồn gốc để bật các tính năng mạnh mẽ trên trình duyệt.
Bảng thuật ngữ
Tài liệu này sử dụng nhiều thuật ngữ có tên và từ viết tắt tương tự nhau. Để làm rõ, chúng tôi đã biên soạn một bảng chú giải ngắn:
- COEP: Chính sách đối với trình nhúng trên nhiều nguồn gốc
- COOP: Chính sách đối với trình mở trên nhiều nguồn gốc
- CORP: Chính sách tài nguyên trên nhiều nguồn gốc
- CORS: Chia sẻ tài nguyên trên nhiều nguồn gốc
- CORB: Chặn đọc trên nhiều nguồn gốc
Thông tin khái quát
Web được xây dựng dựa trên chính sách yêu cầu các trang web phải có cùng nguồn gốc, một tính năng bảo mật hạn chế cách tài liệu và tập lệnh có thể tương tác với các tài nguyên từ một nguồn gốc khác. Nguyên tắc này hạn chế cách các trang web có thể truy cập vào tài nguyên khác nguồn gốc. Ví dụ: một tài liệu từ https://a.example không được phép truy cập vào dữ liệu được lưu trữ tại https://b.example.
Tuy nhiên, chính sách cùng nguồn gốc từng có một số ngoại lệ. Mọi trang web đều có thể:
- Nhúng iframe khác nguồn gốc
- Bao gồm các tài nguyên khác nguồn gốc, chẳng hạn như hình ảnh hoặc tập lệnh
- Mở cửa sổ hộp thoại khác nguồn gốc bằng một tham chiếu DOM
Vào thời điểm cộng đồng web nhận ra lợi ích của chính sách nghiêm ngặt về cùng nguồn gốc, web đã dựa vào những trường hợp ngoại lệ này.
Tác dụng phụ về bảo mật của chính sách cùng nguồn gốc lỏng lẻo như vậy đã được vá theo hai cách:
- Giao thức Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS) đảm bảo rằng máy chủ cho phép chia sẻ tài nguyên với một nguồn gốc nhất định.
- Nhà phát triển ngầm xoá quyền truy cập trực tiếp vào tập lệnh đối với các tài nguyên khác nguồn gốc, đồng thời vẫn duy trì khả năng tương thích ngược. Những tài nguyên khác nguồn gốc như vậy được gọi là tài nguyên "không trong suốt". Đây là lý do thao tác với pixel khác nguồn gốc bằng
CanvasRenderingContext2Dsẽ không thành công, trừ phi CORS được áp dụng cho hình ảnh.
Tất cả các quyết định về chính sách này đều diễn ra trong một nhóm bối cảnh duyệt web.

Trong một thời gian dài, sự kết hợp này đủ để giữ cho trình duyệt an toàn, với một số ít trường hợp đặc biệt cần vá trực tiếp (chẳng hạn như lỗ hổng bảo mật JSON).
Điều này đã thay đổi với Spectre, khiến mọi dữ liệu được tải vào cùng một nhóm bối cảnh duyệt web như mã của bạn có khả năng đọc được. Bằng cách đo thời gian thực hiện một số thao tác nhất định, kẻ tấn công có thể đoán được nội dung của bộ nhớ đệm CPU và do đó, nội dung của bộ nhớ quy trình. Các cuộc tấn công như vậy có thể xảy ra với bộ hẹn giờ có độ chi tiết thấp trong nền tảng và có thể tăng tốc bằng bộ hẹn giờ có độ chi tiết cao, cả bộ hẹn giờ tường minh (chẳng hạn như performance.now()) và bộ hẹn giờ ngầm (chẳng hạn như SharedArrayBuffer).
Nếu evil.com nhúng một hình ảnh từ nhiều nguồn, họ có thể dùng một cuộc tấn công Spectre để đọc dữ liệu pixel của hình ảnh được nhúng. Điều này khiến các biện pháp bảo vệ dựa vào "tính mờ đục" trở nên không hiệu quả.

Tốt nhất là tất cả các yêu cầu khác nguồn gốc đều được máy chủ sở hữu tài nguyên kiểm tra. Nếu không được kiểm tra kỹ lưỡng, thì dữ liệu sẽ không bao giờ được chuyển đến nhóm bối cảnh duyệt web của một tác nhân xấu. Do đó, dữ liệu sẽ nằm ngoài tầm với của các cuộc tấn công Spectre có thể xảy ra. Chúng tôi gọi đây là trạng thái tách biệt trên nhiều nguồn gốc.
Khi mã được nhúng ở trạng thái bị cô lập trên nhiều nguồn, trang web yêu cầu sẽ được coi là ít nguy hiểm hơn. Điều này cho phép trang web yêu cầu sử dụng SharedArrayBuffer, performance.measureUserAgentSpecificMemory() và bộ hẹn giờ có độ phân giải cao với độ chính xác cao hơn, đồng thời ngăn chặn các cuộc tấn công Spectre có thể xảy ra. Trạng thái này cũng ngăn việc sửa đổi document.domain.
Chính sách đối với trình nhúng trên nhiều nguồn gốc
Chính sách đối với trình nhúng trên nhiều nguồn gốc (COEP) ngăn một tài liệu tải bất kỳ tài nguyên trên nhiều nguồn gốc nào không cấp phép rõ ràng cho tài liệu bằng CORP hoặc CORS. Với tính năng này, bạn có thể khai báo rằng một tài liệu không thể tải các tài nguyên đó.
a.example, đặt chính sách COEP thành require-corp. a.example muốn nhúng 3 thành phần từ b.example, nhưng chỉ có 2 thành phần nhúng thành công.
Hai lần nhúng thành công bao gồm một tệp JavaScript có chính sách CORP khác nguồn gốc và một hình ảnh được CORS cho phép. Tài sản thứ ba là một video có chính sách CORP, theo đó, tài sản chỉ được nhúng trên cùng một nguồn gốc. Do đó, video sẽ không được tải trên a.example.
Để kích hoạt chính sách này, hãy thêm tiêu đề HTTP sau vào tài liệu:
Cross-Origin-Embedder-Policy: require-corp
COEP nhận một giá trị duy nhất là require-corp. Điều này thực thi chính sách rằng tài liệu chỉ có thể tải tài nguyên từ cùng một nguồn gốc hoặc tài nguyên được đánh dấu rõ ràng là có thể tải từ một nguồn gốc khác.
Để có thể tải tài nguyên từ một nguồn gốc khác, các tài nguyên đó cần hỗ trợ Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS) hoặc Chính sách về tài nguyên nhiều nguồn gốc (CORP).
Chia sẻ tài nguyên trên nhiều nguồn gốc
Nếu một tài nguyên trên nhiều nguồn gốc hỗ trợ Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS), bạn có thể sử dụng thuộc tính crossorigin để tải tài nguyên đó vào trang web của mình mà không bị COEP chặn.
<img src="https://third-party.example.com/image.jpg" crossorigin>
Ví dụ: nếu tài nguyên hình ảnh này được phân phát bằng tiêu đề CORS, hãy sử dụng thuộc tính crossorigin để yêu cầu tìm nạp tài nguyên sẽ sử dụng chế độ CORS. Điều này cũng ngăn hình ảnh tải trừ phi hình ảnh đó đặt tiêu đề CORS.
Tương tự, bạn có thể tìm nạp dữ liệu trên nhiều nguồn gốc thông qua phương thức fetch(). Phương thức này không yêu cầu xử lý đặc biệt miễn là máy chủ phản hồi bằng các tiêu đề HTTP phù hợp.
Chính sách tài nguyên trên nhiều nguồn gốc
Chính sách Chia sẻ tài nguyên trên nhiều nguồn gốc (CORP) ban đầu được giới thiệu dưới dạng một lựa chọn không bắt buộc để bảo vệ tài nguyên của bạn khỏi bị một nguồn gốc khác tải. Trong bối cảnh COEP, CORP có thể chỉ định chính sách của chủ sở hữu tài nguyên về những người có thể tải tài nguyên.
Tiêu đề Cross-Origin-Resource-Policy có thể có 3 giá trị:
Cross-Origin-Resource-Policy: same-site
Bạn chỉ có thể tải các tài nguyên được đánh dấu same-site từ cùng một trang web.
Cross-Origin-Resource-Policy: same-origin
Bạn chỉ có thể tải các tài nguyên được đánh dấu same-origin từ cùng một nguồn.
Cross-Origin-Resource-Policy: cross-origin
Mọi trang web đều có thể tải các tài nguyên được đánh dấu cross-origin. (Giá trị này đã được thêm vào quy cách CORP cùng với COEP.)
Cross Origin Opener Policy
Chính sách Cross-Origin-Opener-Policy (COOP) cho phép bạn tách biệt một cửa sổ cấp cao nhất với các tài liệu khác bằng cách đặt các tài liệu đó vào một nhóm ngữ cảnh duyệt web riêng biệt. Bằng cách này, các tài liệu không thể tương tác trực tiếp với cửa sổ cấp cao nhất. Ví dụ: nếu một tài liệu có COOP mở một hộp thoại, thì thuộc tính window.opener của tài liệu đó là null. Thuộc tính .closed của giá trị tham chiếu của trình mở là true.

Tiêu đề Cross-Origin-Opener-Policy có thể có 3 giá trị:
Cross-Origin-Opener-Policy: same-origin
Các tài liệu được đánh dấu same-origin có thể dùng chung cùng một nhóm ngữ cảnh duyệt web với các tài liệu có cùng nguồn gốc cũng được đánh dấu rõ ràng là same-origin.

Cross-Origin-Opener-Policy: same-origin-allow-popups
Một tài liệu cấp cao nhất có same-origin-allow-popups sẽ giữ lại các tham chiếu đến mọi cửa sổ bật lên không đặt COOP hoặc chọn không tách biệt bằng cách đặt COOP là unsafe-none.

Cross-Origin-Opener-Policy: unsafe-none
unsafe-none là giá trị mặc định và cho phép thêm tài liệu vào nhóm bối cảnh duyệt web của trình mở, trừ phi trình mở có COOP là same-origin.
Tóm tắt
Nếu muốn sử dụng các tính năng như SharedArrayBuffer, performance.measureUserAgentSpecificMemory() hoặc bộ hẹn giờ có độ phân giải cao với độ chính xác cao hơn, tài liệu của bạn cần sử dụng cả COEP có giá trị là require-corp và COOP có giá trị là same-origin. Nếu không có cả hai, trình duyệt sẽ không đảm bảo đủ khả năng cách ly để bật an toàn những tính năng mạnh mẽ đó.
Bạn có thể xác định tình huống của trang bằng cách kiểm tra xem self.crossOriginIsolated có trả về true hay không.
Tìm hiểu cách triển khai tính năng này trong bài viết Biến trang web của bạn thành "cross-origin isolated" (được cách ly trên nhiều nguồn gốc) bằng COOP và COEP.