Sử dụng COOP và COEP để thiết lập môi trường tách biệt trên nhiều nguồn gốc và bật các tính năng mạnh mẽ như SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
và bộ hẹn giờ có độ phân giải cao với độ chính xác cao hơn.
Thông tin cập nhật
- Ngày 21 tháng 6 năm 2022: Bạn cũng cần cẩn thận với các tập lệnh worker khi bật tính năng tách biệt nhiều nguồn gốc. Thêm một số nội dung giải thích.
- Ngày 5 tháng 8 năm 2021: API tự phân tích tài nguyên JS đã được đề cập là một trong những API yêu cầu tách biệt nhiều nguồn gốc, nhưng phản ánh thay đổi gần đây về hướng, API này đã bị xoá.
- Ngày 6 tháng 5 năm 2021: Dựa trên ý kiến phản hồi và các vấn đề được báo cáo, chúng tôi đã quyết định điều chỉnh tiến trình hạn chế việc sử dụng
SharedArrayBuffer
trong các trang web không tách biệt nhiều nguồn gốc trong Chrome M92. - Ngày 16 tháng 4 năm 2021: Thêm ghi chú về chế độ không dùng thông tin xác thực COEP mới và COOP same-origin-allow- Nội dung bật lên để làm điều kiện dễ dàng để tách biệt nhiều nguồn gốc.
- Ngày 5 tháng 3 năm 2021: Xoá các giới hạn đối với
SharedArrayBuffer
,performance.measureUserAgentSpecificMemory()
và các chức năng gỡ lỗi, hiện đã được bật đầy đủ trong Chrome 89. Thêm các tính năng sắp ra mắt,performance.now()
vàperformance.timeOrigin
, sẽ có độ chính xác cao hơn. - Ngày 19 tháng 2 năm 2021: Thêm ghi chú về chính sách tính năng
allow="cross-origin-isolated"
và chức năng gỡ lỗi trên DevTools. - Ngày 15 tháng 10 năm 2020:
self.crossOriginIsolated
có trong Chrome 87. Do đó,document.domain
là không thể thay đổi khiself.crossOriginIsolated
trả vềtrue
.performance.measureUserAgentSpecificMemory()
sẽ kết thúc thử nghiệm về nguồn gốc và được bật theo mặc định trong Chrome 89. Vùng đệm mảng dùng chung trên Chrome cho Android sẽ có trong Chrome 88.
Một số API web làm tăng nguy cơ bị tấn công kênh bên như Spectre. Để giảm thiểu rủi ro đó, trình duyệt cung cấp một môi trường tách biệt dựa trên lựa chọn sử dụng có tên là tách biệt nhiều nguồn gốc. Với trạng thái tách biệt nhiều nguồn gốc, trang web sẽ có thể sử dụng các tính năng đặc quyền, bao gồm:
API | Mô tả |
---|---|
SharedArrayBuffer
|
Bắt buộc đối với luồng WebAssembly. Tính năng này có trên Android Chrome 88. Phiên bản máy tính hiện được bật theo mặc định nhờ tính năng Tách biệt trang web, nhưng sẽ yêu cầu trạng thái tách biệt nhiều nguồn gốc và sẽ bị tắt theo mặc định trong Chrome 92. |
performance.measureUserAgentSpecificMemory()
|
Có trong Chrome 89. |
performance.now() , performance.timeOrigin
|
Tính năng này hiện hoạt động trong nhiều trình duyệt với độ phân giải giới hạn ở mức 100 micrô giây trở lên. Với tính năng tách biệt nhiều nguồn gốc, độ phân giải có thể là 5 micro giây trở lên. |
Trạng thái tách biệt nhiều nguồn gốc cũng ngăn chặn việc sửa đổi document.domain
. (Khả năng thay đổi document.domain
cho phép giao tiếp giữa các tài liệu trên cùng một trang web và được coi là một lỗ hổng trong chính sách về cùng một nguồn gốc.)
Để chọn sử dụng trạng thái tách biệt nhiều nguồn gốc, bạn cần gửi các tiêu đề HTTP sau trên tài liệu chính:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Các tiêu đề này hướng dẫn trình duyệt chặn việc tải tài nguyên hoặc iframe chưa chọn tải bằng tài liệu trên nhiều nguồn gốc và ngăn cửa sổ trên nhiều nguồn gốc tương tác trực tiếp với tài liệu của bạn. Điều này cũng có nghĩa là những tài nguyên được tải trên nhiều nguồn gốc cần phải chọn sử dụng.
Bạn có thể xác định xem một trang web có đang ở trạng thái tách biệt nhiều nguồn gốc hay không bằng cách
kiểm tra
self.crossOriginIsolated
.
Bài viết này hướng dẫn cách sử dụng các tiêu đề mới này. Trong bài viết tiếp theo, tôi sẽ cung cấp thêm thông tin cơ bản và ngữ cảnh.
Triển khai COOP và COEP để tách biệt các nguồn gốc trên trang web
Tích hợp COOP và COEP
1. Đặt tiêu đề Cross-Origin-Opener-Policy: same-origin
trên tài liệu cấp cao nhất
Khi bật COOP: same-origin
trên một tài liệu cấp cao nhất, các cửa sổ có cùng nguồn gốc và các cửa sổ mở từ tài liệu đó sẽ có một nhóm ngữ cảnh duyệt web riêng biệt, trừ phi các cửa sổ đó có cùng nguồn gốc có cùng chế độ cài đặt COOP.
Do đó, tính năng tách biệt được thực thi cho các cửa sổ đã mở và tính năng giao tiếp lẫn nhau giữa cả hai cửa sổ bị tắt.
Nhóm ngữ cảnh duyệt web là một tập hợp các cửa sổ có thể tham chiếu lẫn nhau. Ví dụ: một tài liệu cấp cao nhất và các tài liệu con của tài liệu đó được nhúng thông qua <iframe>
.
Nếu một trang web (https://a.example
) mở cửa sổ bật lên (https://b.example
), cửa sổ trình mở và cửa sổ bật lên có cùng ngữ cảnh duyệt web, do đó, các trang web này có quyền truy cập vào nhau thông qua các API DOM, chẳng hạn như window.opener
.
Bạn có thể kiểm tra xem trình mở cửa sổ và trình mở của trình mở đó có nằm trong các nhóm ngữ cảnh duyệt web riêng biệt từ DevTools hay không.
2. Đảm bảo tài nguyên đã bật CORP hoặc CORS
Đảm bảo rằng tất cả tài nguyên trong trang đều được tải bằng tiêu đề HTTP CORP hoặc CORS. Bước này là bắt buộc đối với bước 4, bật COEP.
Dưới đây là những việc bạn cần làm tuỳ thuộc vào bản chất của tài nguyên:
- Nếu tài nguyên dự kiến sẽ được tải chỉ từ cùng một nguồn gốc, hãy đặt tiêu đề
Cross-Origin-Resource-Policy: same-origin
. - Nếu tài nguyên dự kiến sẽ được tải chỉ từ cùng một trang web nhưng có nhiều nguồn gốc, hãy đặt tiêu đề
Cross-Origin-Resource-Policy: same-site
. - Nếu tài nguyên được tải từ (các) nguồn gốc khác nhau mà bạn kiểm soát, hãy đặt tiêu đề
Cross-Origin-Resource-Policy: cross-origin
nếu có thể. - Đối với các tài nguyên trên nhiều nguồn gốc mà bạn không kiểm soát được:
- Sử dụng thuộc tính
crossorigin
trong thẻ HTML đang tải nếu tài nguyên được phân phát bằng CORS. (Ví dụ:<img src="***" crossorigin>
.) - Yêu cầu chủ sở hữu tài nguyên hỗ trợ CORS hoặc CORP.
- Sử dụng thuộc tính
- Đối với iframe, hãy làm theo các nguyên tắc tương tự ở trên và đặt
Cross-Origin-Resource-Policy: cross-origin
(hoặcsame-site
,same-origin
tuỳ thuộc vào ngữ cảnh). - Các tập lệnh được tải bằng
WebWorker
phải được phân phát từ cùng một nguồn gốc, vì vậy, bạn không cần tiêu đề CORP hoặc CORS. - Đối với tài liệu hoặc worker được phân phát bằng
COEP: require-corp
, các tài nguyên phụ nhiều nguồn gốc được tải mà không có CORS phải đặt tiêu đềCross-Origin-Resource-Policy: cross-origin
để chọn nhúng. Ví dụ: điều này áp dụng cho<script>
,importScripts
,<link>
,<video>
,<iframe>
, v.v.
3. Sử dụng tiêu đề HTTP Chỉ báo cáo COEP để đánh giá tài nguyên được nhúng
Trước khi bật đầy đủ COEP, bạn có thể chạy thử bằng cách sử dụng tiêu đề Cross-Origin-Embedder-Policy-Report-Only
để kiểm tra xem chính sách có thực sự hoạt động hay không. Bạn sẽ nhận được báo cáo mà không cần chặn nội dung được nhúng.
Áp dụng định kỳ này cho tất cả tài liệu, bao gồm cả tài liệu cấp cao nhất, iframe và tập lệnh trình thực thi. Để biết thông tin về tiêu đề HTTP Chỉ báo cáo, hãy xem phần Quan sát vấn đề bằng API Báo cáo.
4. Bật COEP
Sau khi bạn xác nhận rằng mọi thứ đều hoạt động và tất cả tài nguyên đều có thể được tải thành công, hãy chuyển tiêu đề Cross-Origin-Embedder-Policy-Report-Only
sang tiêu đề Cross-Origin-Embedder-Policy
có cùng giá trị cho tất cả tài liệu, bao gồm cả những tài liệu được nhúng thông qua iframe và tập lệnh worker.
Xác định xem việc tách biệt có thành công bằng self.crossOriginIsolated
hay không
Thuộc tính self.crossOriginIsolated
trả về true
khi trang web ở trạng thái tách biệt nhiều nguồn gốc, đồng thời tất cả tài nguyên và cửa sổ bị tách biệt trong cùng một nhóm ngữ cảnh duyệt web. Bạn có thể sử dụng API này để xác định xem mình đã tách biệt thành công nhóm ngữ cảnh duyệt web và có quyền truy cập vào các tính năng mạnh mẽ như performance.measureUserAgentSpecificMemory()
hay chưa.
Gỡ lỗi bằng Công cụ của Chrome cho nhà phát triển
Đối với các tài nguyên được hiển thị trên màn hình như hình ảnh, bạn có thể dễ dàng phát hiện các vấn đề về COEP vì yêu cầu sẽ bị chặn và trang sẽ cho biết hình ảnh bị thiếu. Tuy nhiên, đối với các tài nguyên không nhất thiết phải có tác động trực quan, chẳng hạn như tập lệnh hoặc kiểu, các vấn đề về COEP có thể không được phát hiện. Trong trường hợp đó, hãy sử dụng bảng điều khiển Mạng Công cụ cho nhà phát triển. Nếu có vấn đề với COEP, bạn sẽ thấy (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep)
trong cột Trạng thái.
Sau đó, bạn có thể nhấp vào mục đó để xem thêm thông tin chi tiết.
Bạn cũng có thể xác định trạng thái của iframe và cửa sổ bật lên thông qua bảng điều khiển Application (Ứng dụng). Chuyển đến phần "Khung" ở bên trái và mở rộng "trên cùng" để xem thông tin chi tiết về cấu trúc tài nguyên.
Bạn có thể kiểm tra trạng thái của iframe, chẳng hạn như tình trạng có sẵn của SharedArrayBuffer
,
v.v.
Bạn cũng có thể kiểm tra trạng thái của cửa sổ bật lên, chẳng hạn như liệu cửa sổ đó có được tách biệt giữa các nguồn gốc hay không.
Quan sát các vấn đề bằng API Báo cáo
Reporting API là một cơ chế khác mà bạn có thể sử dụng để phát hiện nhiều vấn đề. Bạn có thể định cấu hình API Báo cáo để hướng dẫn trình duyệt của người dùng gửi báo cáo bất cứ khi nào COEP chặn việc tải tài nguyên hoặc COOP tách biệt một cửa sổ bật lên. Chrome đã hỗ trợ API Báo cáo kể từ phiên bản 69 cho nhiều mục đích sử dụng, bao gồm cả COEP và COOP.
Để tìm hiểu cách định cấu hình API Báo cáo và thiết lập máy chủ để nhận báo cáo, hãy xem phần Sử dụng API Báo cáo.
Ví dụ về báo cáo COEP
Ví dụ về tải trọng báo cáo về COEP khi tài nguyên nhiều nguồn gốc bị chặn có dạng như sau:
[{
"age": 25101,
"body": {
"blocked-url": "https://third-party-test.glitch.me/check.svg?",
"blockedURL": "https://third-party-test.glitch.me/check.svg?",
"destination": "image",
"disposition": "enforce",
"type": "corp"
},
"type": "coep",
"url": "https://cross-origin-isolation.glitch.me/?coep=require-corp&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]
Ví dụ về báo cáo COOP
Ví dụ về tải trọng báo cáo COOP khi một cửa sổ bật lên được mở riêng biệt sẽ có dạng như sau:
[{
"age": 7,
"body": {
"disposition": "enforce",
"effectivePolicy": "same-origin",
"nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
"type": "navigation-from-response"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/coop?coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]
Khi các nhóm ngữ cảnh duyệt web khác nhau cố gắng truy cập vào nhau (chỉ ở chế độ "chỉ báo cáo"), COOP cũng sẽ gửi một báo cáo. Ví dụ: báo cáo khi cố gắng postMessage()
sẽ có dạng như sau:
[{
"age": 51785,
"body": {
"columnNumber": 18,
"disposition": "reporting",
"effectivePolicy": "same-origin",
"lineNumber": 83,
"property": "postMessage",
"sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
"type": "access-from-coop-page-to-openee"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
"age": 51785,
"body": {
"disposition": "reporting",
"effectivePolicy": "same-origin",
"property": "postMessage",
"type": "access-to-coop-page-from-openee"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]
Kết luận
Sử dụng kết hợp các tiêu đề HTTP COOP và COEP để chọn một trang web chuyển sang trạng thái tách biệt đặc biệt giữa các nguồn gốc. Bạn có thể kiểm tra self.crossOriginIsolated
để xác định xem một trang web có ở trạng thái tách biệt nhiều nguồn gốc hay không.
Chúng tôi sẽ cập nhật bài đăng này khi các tính năng mới được cung cấp cho trạng thái tách biệt nhiều nguồn gốc này, đồng thời cải tiến thêm cho DevTools liên quan đến COOP và COEP.
Tài nguyên
- Lý do bạn cần "tách riêng trên nhiều nguồn gốc" để có các tính năng mạnh mẽ
- Hướng dẫn bật tính năng tách biệt nhiều nguồn gốc
- Nội dung cập nhật SharedArrayBuffer trong Chrome 88 dành cho Android và Chrome 92 dành cho máy tính
- Theo dõi tổng mức sử dụng bộ nhớ của trang web bằng
measureUserAgentSpecificMemory()