Permissions-Policy header thực sự có thể khóa chặt những gì
Hướng dẫn thực tế về các tính năng trình duyệt mà bạn có thể hạn chế, những gì bạn không thể kiểm soát, và cách triển khai header mà không làm hỏng chức năng hữu ích.
Mục lục
- Phiên bản ngắn gọn
- Permissions-Policy kiểm soát những gì
- Nó có thể khóa chặt những gì trên các trang của chính bạn
- Nó có thể khóa chặt những gì trong iframe
- Những gì nó không thể khóa chặt
- Một policy mặc định hợp lý
- Cách triển khai mà không làm hỏng mọi thứ
- 1. Lập inventory việc sử dụng tính năng
- 2. Bắt đầu trong môi trường rủi ro thấp
- 3. Dùng policy theo từng trang khi cần
- 4. Xác minh response thực
- 5. Ghi lại các ngoại lệ
- Các lỗi cú pháp thường gặp
- Giá trị quyền riêng tư thực tế
Phiên bản ngắn gọn
Permissions-Policy là một HTTP response header cho phép một site giới hạn quyền truy cập vào một số tính năng trình duyệt nhất định: camera, microphone, geolocation, fullscreen, payment, sensors, và một danh sách dài các API nhỏ hơn.
Nó không phải là một lá chắn quyền riêng tư tổng quát. Nó sẽ không chặn toàn bộ tracking, chặn cookies, ngăn network requests, hay làm cho JavaScript bên thứ ba trở nên an toàn. Điều nó làm tốt có phạm vi hẹp hơn nhưng vẫn có giá trị: giảm các năng lực trình duyệt khả dụng cho chính các trang của bạn và cho các frame được nhúng.
Điều đó quan trọng vì các website hiện đại được ghép lại từ analytics snippets, media embeds, chat widgets, consent managers, advertising scripts, maps, payment flows, và các thử nghiệm nội bộ. Phần lớn các thành phần đó không cần quyền truy cập vào những device API mạnh. Một policy tốt sẽ làm điều đó trở nên rõ ràng.
Nếu bạn đã rà soát headers trong production, hãy kết hợp việc này với một lần kiểm tra trực tiếp response thực tế. Hướng dẫn của chúng tôi về debugging redirects and HTTP headers in production đề cập đến thói quen quan trọng ở đây: kiểm tra những gì trình duyệt thực sự nhận được, không phải những gì file cấu hình của bạn nói rằng sẽ xảy ra.
Permissions-Policy kiểm soát những gì
Header này kiểm soát quyền truy cập vào các tính năng trình duyệt được đặt tên. Danh sách chính xác thay đổi theo thời gian vì browser APIs thay đổi, nhưng các directive phổ biến gồm:
cameramicrophonegeolocationfullscreenpaymentusbbluetoothaccelerometergyroscopemagnetometerscreen-wake-lockclipboard-readclipboard-writepublickey-credentials-getinterest-cohorttrong các thảo luận cũ hơn, hiện chủ yếu chỉ còn ý nghĩa lịch sử
Một directive có thể cho phép một tính năng cho không ai cả, cho origin hiện tại, hoặc cho các origin được chọn. Ví dụ:
Permissions-Policy: camera=(), microphone=(), geolocation=(self)
Điều này có nghĩa là camera và microphone bị vô hiệu hóa cho document và các nested browsing contexts của nó, trong khi geolocation chỉ được cho phép với cùng origin.
Một ví dụ cởi mở hơn:
Permissions-Policy: geolocation=(self "https://maps.example"), fullscreen=(self "https://video.example")
Điều này cho phép origin của chính bạn và một nhà cung cấp bản đồ được nêu tên sử dụng geolocation, đồng thời cho phép origin của bạn cùng một nhà cung cấp video yêu cầu fullscreen.
Policy được trình duyệt đánh giá. Nếu một tính năng bị từ chối, JavaScript sử dụng API đó sẽ thất bại hoặc hành xử như thể tính năng không khả dụng. Cách thất bại chính xác phụ thuộc vào API. Đôi khi một promise bị reject. Đôi khi một capability đơn giản là không xuất hiện như có thể sử dụng được.
Nó có thể khóa chặt những gì trên các trang của chính bạn
Trên các trang first-party, Permissions-Policy hữu ích nhất như một lan can bảo vệ. Nó giảm phạm vi tác động của mã vô tình hoặc không mong đợi.
Ví dụ, một trang marketing có lẽ không cần microphone, camera, Bluetooth, USB, motion sensors, hay payment APIs. Bạn có thể từ chối các tính năng đó trên toàn cục:
Permissions-Policy: camera=(), microphone=(), bluetooth=(), usb=(), payment=(), accelerometer=(), gyroscope=(), magnetometer=()
Điều đó không làm cho mọi script trên trang trở nên đáng tin cậy. Nó có nghĩa là nếu một thử nghiệm trong tag manager, dependency bị xâm phạm, hoặc widget được dán vào cố gọi một API bị hạn chế, trình duyệt không nên cấp quyền truy cập cho nó.
Với các nhóm có nhiều người đóng góp, đây là một mặc định hữu ích. Nó chuyển cuộc thảo luận từ niềm tin mơ hồ sang năng lực được nêu rõ. Nếu một tính năng tương lai thực sự cần camera, ai đó phải thay đổi policy và giải thích lý do.
Đó là loại ma sát phù hợp.
Nó có thể khóa chặt những gì trong iframe
Header này trở nên đặc biệt hữu ích với nội dung được nhúng.
Trình duyệt vốn đã xem iframe là các browsing context riêng biệt, nhưng nội dung bên thứ ba được nhúng vẫn có thể yêu cầu các tính năng mạnh nếu được policy và thuộc tính iframe cho phép. Permissions-Policy cho phép trang cha đặt một mức trần.
Ví dụ, nếu trang của bạn nhúng một video player, một support widget, và một bản đồ, bạn có thể tránh cấp cho mọi frame quyền truy cập vào mọi tính năng. Bạn có thể chỉ cho phép fullscreen với video frame và chỉ cho phép geolocation với map frame.
Có hai lớp cần hiểu:
- HTTP
Permissions-Policyheader đặt policy cho document. - Thuộc tính iframe
allowcó thể ủy quyền các tính năng cụ thể cho một frame, nhưng chỉ trong phạm vi policy của trang cha cho phép.
Một iframe đơn giản có thể trông như sau:
<iframe src="https://video.example/embed/123" allow="fullscreen"></iframe>
Nếu header của bạn từ chối fullscreen hoàn toàn, thuộc tính iframe không thể ghi đè sự từ chối đó. Nếu header của bạn cho phép fullscreen cho origin đó, thuộc tính iframe có thể ủy quyền nó.
Hệ phân cấp này là một lý do khiến header đáng sử dụng. Nó cho các nhóm platform hoặc security một cách đặt ranh giới toàn site, trong khi vẫn cho phép các nhóm product bật các embed cụ thể khi cần.
Những gì nó không thể khóa chặt
Đây là nơi các nhóm đôi khi đánh giá quá cao header này.
Permissions-Policy không thay thế content security policy. Nó không quyết định script nào được phép tải. Nó không ngăn một script gửi dữ liệu qua mạng. Nó không sanitize HTML. Nó không ngăn XSS. Nó không chặn form spam. Nếu form abuse là vấn đề, hãy bắt đầu với cơ chế được mô tả trong why your contact form is your biggest spam liability, không phải với header này.
Nó cũng không thay thế việc quản trị cookies. Cookies, local storage, consent, third-party embeds, và browser tracking protections là các vấn đề riêng. Nếu bạn đang rà soát rộng hơn các biện pháp kiểm soát quyền riêng tư, bức tranh cookies xứng đáng có một vòng đánh giá riêng; các thay đổi thực tế được trình bày trong what changed for cookies in 2026 and what to do about it.
Quan trọng nhất, Permissions-Policy không làm cho JavaScript bên thứ ba trở nên riêng tư. Nếu bạn tải một script bên thứ ba vào trang first-party của mình, nhìn chung nó chạy với đặc quyền của trang bạn, tùy thuộc vào các ràng buộc trình duyệt khác và security headers của bạn. Từ chối quyền truy cập camera là tốt. Nhưng điều đó không ngăn script đó đọc nội dung DOM, quan sát hành động người dùng, hoặc thực hiện các network requests được phép.
Để làm việc đó, bạn cần các biện pháp kiểm soát khác: chọn vendor cẩn thận, CSP, sandboxed iframes, Subresource Integrity khi áp dụng được, data minimization, và những đợt rà soát nhàm chán nhưng cần thiết.
Một policy mặc định hợp lý
Không có header phổ quát nào phù hợp với mọi site, nhưng hầu hết các site nội dung và marketing có thể bắt đầu theo hướng hạn chế.
Một lần triển khai đầu tiên hợp lý:
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), bluetooth=(), accelerometer=(), gyroscope=(), magnetometer=(), screen-wake-lock=()
Sau đó chỉ thêm lại những gì site thực sự sử dụng.
Ví dụ:
- Một cửa hàng dùng Payment Request API có thể cần
payment=(self). - Một trình tìm địa điểm có thể cần
geolocation=(self)hoặc một map origin đáng tin cậy. - Một ứng dụng hội nghị có thể cần
camera=(self)vàmicrophone=(self). - Một site nhiều video có thể cần
fullscreen=(self "https://trusted-video.example").
Điểm quan trọng không phải là sao chép một policy khổng lồ từ checklist rồi coi như xong. Hãy bắt đầu từ inventory tính năng của bạn. Trang nào cần capability trình duyệt nào? Embed nào cần delegation? Tính năng nào sẽ gây bất ngờ nếu được yêu cầu?
Cách triển khai mà không làm hỏng mọi thứ
Hãy rollout việc này như bất kỳ production header nào khác: có chủ đích.
1. Lập inventory việc sử dụng tính năng
Tìm trong codebase các lệnh gọi browser API như getUserMedia, geolocation, requestFullscreen, PaymentRequest, Web Bluetooth, WebUSB, và wake lock APIs.
Sau đó kiểm tra third-party embeds. Tài liệu của các nhà cung cấp video, maps, payment, và identity thường đề cập đến các giá trị iframe allow bắt buộc.
2. Bắt đầu trong môi trường rủi ro thấp
Thêm một header hạn chế trong staging và kiểm thử các hành trình cốt lõi. Chú ý đến thông báo trong browser console. Trình duyệt thường báo khi một tính năng bị chặn bởi permissions policy.
3. Dùng policy theo từng trang khi cần
Đừng ép một policy toàn cục nếu sản phẩm của bạn có các loại trang rất khác nhau. Một blog, checkout, map page, và video room có lẽ cần những capability khác nhau.
Hầu hết web servers, frameworks, và edge platforms đều có thể đặt headers có điều kiện theo path. Cách đó thường sạch hơn so với làm yếu toàn bộ site chỉ vì một tính năng.
4. Xác minh response thực
Headers có thể được thêm, ghi đè, nhân đôi, hoặc bị loại bỏ bởi CDNs, reverse proxies, app servers, và middleware. Hãy kiểm tra response cuối cùng trong browser DevTools hoặc bằng command-line tools.
Cũng hãy kiểm thử embedded contexts. Một trang top-level trông đúng không đảm bảo rằng iframe đã nhận được delegation bạn dự định.
5. Ghi lại các ngoại lệ
Mỗi tính năng được cho phép nên có một owner và một lý do. Điều này nghe có vẻ quan liêu cho đến sáu tháng sau, khi không ai còn nhớ vì sao geolocation được mở cho một vendor domain không còn xuất hiện trên trang.
Các lỗi cú pháp thường gặp
Cú pháp header hiện đại ngắn gọn nhưng dễ sai một chút.
Dùng cặp ngoặc đơn rỗng để từ chối một tính năng:
Permissions-Policy: microphone=()
Dùng self cho origin hiện tại:
Permissions-Policy: geolocation=(self)
Dùng origin có dấu ngoặc kép cho các origin bên ngoài cụ thể:
Permissions-Policy: fullscreen=(self "https://video.example")
Tránh dựa vào các ví dụ Feature-Policy cũ trừ khi bạn cố ý hỗ trợ hành vi legacy. Header cũ dùng cú pháp khác và không phải là thứ bạn nên lấy làm nền tảng thiết kế hôm nay.
Cũng cần nhớ rằng hỗ trợ trình duyệt thay đổi theo từng directive. Một trình duyệt có thể hỗ trợ header nhưng không hỗ trợ một feature directive cụ thể. Điều đó là bình thường. Hãy xem header này như một biện pháp defense-in-depth, không phải biện pháp kiểm soát quyền riêng tư hay bảo mật duy nhất của bạn.
<!-- tool-cta:start -->
💡 Hãy thử cách này: Xác minh rằng Permissions-Policy của bạn đang được phân phối như dự định bằng Get Headers, công cụ hiển thị các tiêu đề phản hồi thô mà máy chủ của bạn đang gửi.
<!-- tool-cta:end -->
Giá trị quyền riêng tư thực tế
Giá trị quyền riêng tư của Permissions-Policy không phải là làm cho một site ẩn danh hoặc không có tracker. Nó không làm được điều đó.
Giá trị của nó là thu hẹp quyền truy cập vào các capability trình duyệt nhạy cảm. Location, camera, microphone, device sensors, local hardware APIs, và payment flows đều mạnh. Phần lớn các trang không cần chúng. Nhiều thành phần được nhúng không bao giờ nên có khả năng yêu cầu chúng.
Đó là một cải thiện thực sự. Nó giảm các prompt vô tình, hạn chế phơi bày capability không cần thiết, và cho nhóm của bạn một artifact cụ thể để rà soát khi chức năng mới được phát hành.
Phiên bản tốt nhất của header này là nhàm chán: hạn chế theo mặc định, chỉ nới lỏng nơi một tính năng hướng tới người dùng yêu cầu, và được kiểm thử như một phần của quy trình phát hành bình thường.