No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

permissions-policy-apache.conf.md 5.6 KiB

hace 6 días
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. # Permissions-Policy reporting (Apache)
  2. The live `Permissions-Policy` header denies features with an empty allowlist
  3. (`feature=()` — grant to nobody). That header does **not** send reports by
  4. itself.
  5. Unlike CSP, Permissions-Policy has **no `report-uri`**. Reporting uses the
  6. Reporting API: a named endpoint in `Reporting-Endpoints`, plus a per-feature
  7. `report-to` parameter.
  8. Reuse the existing CSP collector:
  9. - UAT: `https://pnspsuat.gld.gov.hk/api/csp-report`
  10. - PROD: `https://pnsps.gld.gov.hk/api/csp-report`
  11. Backend: `CspReportController` (`POST /csp-report`) already logs the raw JSON
  12. and `Content-Type` and returns `204`. No backend change is required.
  13. See also: [csp-apache.conf.md](./csp-apache.conf.md)
  14. ## Why not `report-uri`
  15. This CSP-style trailer does **not** produce Permissions-Policy reports:
  16. ```apache
  17. # Wrong — browsers ignore report-uri on Permissions-Policy
  18. Header always set Permissions-Policy "camera=(), geolocation=(); report-uri https://pnspsuat.gld.gov.hk/api/csp-report"
  19. ```
  20. `report-to` is a **parameter of each feature**, not a global trailing directive.
  21. ## Does every feature need `report-to`?
  22. Yes, **if you want a report for that feature**.
  23. - `feature=()` — still blocked, but silent (no report)
  24. - `feature=();report-to=csp-endpoint` — blocked **and** reported
  25. There is no `all=()` reporter and no header-level `report-to` that applies to
  26. every feature. Add `;report-to=csp-endpoint` only on features you want in the
  27. log. Leave the rest as `()` if you do not need those reports.
  28. ```apache
  29. # camera is reported; geolocation is still blocked, but not reported
  30. Header always set Permissions-Policy "camera=();report-to=csp-endpoint, geolocation=()"
  31. ```
  32. ## Enforcing + reporting
  33. Keep the current deny-all policy. Add `Reporting-Endpoints`, then append
  34. `;report-to=csp-endpoint` on each feature you want to monitor.
  35. Copy the feature list from the live header; only the `report-to` parameter is
  36. new. Example (UAT):
  37. ```apache
  38. Header always set Reporting-Endpoints "csp-endpoint=\"https://pnspsuat.gld.gov.hk/api/csp-report\""
  39. Header always set Permissions-Policy "\
  40. accelerometer=();report-to=csp-endpoint, \
  41. autoplay=();report-to=csp-endpoint, \
  42. camera=();report-to=csp-endpoint, \
  43. display-capture=();report-to=csp-endpoint, \
  44. encrypted-media=();report-to=csp-endpoint, \
  45. fullscreen=();report-to=csp-endpoint, \
  46. geolocation=();report-to=csp-endpoint, \
  47. gyroscope=();report-to=csp-endpoint, \
  48. magnetometer=();report-to=csp-endpoint, \
  49. microphone=();report-to=csp-endpoint, \
  50. midi=();report-to=csp-endpoint, \
  51. payment=();report-to=csp-endpoint, \
  52. picture-in-picture=();report-to=csp-endpoint, \
  53. publickey-credentials-get=();report-to=csp-endpoint, \
  54. screen-wake-lock=();report-to=csp-endpoint, \
  55. usb=();report-to=csp-endpoint, \
  56. web-share=();report-to=csp-endpoint, \
  57. xr-spatial-tracking=();report-to=csp-endpoint"
  58. ```
  59. PROD: same headers, with
  60. `https://pnsps.gld.gov.hk/api/csp-report`
  61. Because deny-all is already enforced, put `report-to` on **`Permissions-Policy`**
  62. (not only Report-Only). Those reports have `disposition: "enforce"`.
  63. ## Report-Only (observe without blocking)
  64. Use `Permissions-Policy-Report-Only` only when testing a restriction that is
  65. **not** already denied by the enforcing header. Reports have
  66. `disposition: "report"`.
  67. ```apache
  68. Header always set Reporting-Endpoints "csp-endpoint=\"https://pnspsuat.gld.gov.hk/api/csp-report\""
  69. Header always set Permissions-Policy-Report-Only "geolocation=();report-to=csp-endpoint"
  70. ```
  71. Report-Only cannot re-enable a feature already denied by `Permissions-Policy`.
  72. ## Same URL, different payload
  73. Keep CSP on `report-uri` as it is. The collector URL is shared; the body is not.
  74. | Source | `Content-Type` | Body |
  75. | --- | --- | --- |
  76. | CSP `report-uri` | `application/csp-report` | `{ "csp-report": { … } }` |
  77. | Permissions-Policy | `application/reports+json` | JSON **array**, `type` = `permissions-policy-violation` |
  78. Example Permissions-Policy report:
  79. ```json
  80. [{
  81. "type": "permissions-policy-violation",
  82. "url": "https://pnspsuat.gld.gov.hk/",
  83. "body": {
  84. "disposition": "enforce",
  85. "featureId": "geolocation",
  86. "message": "Permissions policy violation: geolocation access has been blocked because of a permissions policy applied to the current document."
  87. }
  88. }]
  89. ```
  90. Chrome often serializes the feature as `policyId` instead of `featureId`. Filter
  91. logs on `permissions-policy-violation` vs `csp-report` so the two streams stay
  92. distinct.
  93. Optional: also point CSP at the same named endpoint (CSP `report-uri` remains
  94. for older browsers):
  95. ```apache
  96. Header always set Content-Security-Policy-Report-Only "…; report-uri https://pnspsuat.gld.gov.hk/api/csp-report; report-to csp-endpoint"
  97. ```
  98. ## Follow-up checklist
  99. - [ ] Confirm the live Apache `Permissions-Policy` feature list (deny-all `()`).
  100. - [ ] Add `Reporting-Endpoints` → existing `/api/csp-report` (UAT vs PROD host).
  101. - [ ] Add `;report-to=csp-endpoint` only on features you want in the log.
  102. - [ ] Deploy to UAT first; trigger a blocked API (e.g. `navigator.geolocation`) in Chrome/Edge.
  103. - [ ] Confirm a `permissions-policy-violation` line in the backend log (may be batched, a few seconds later).
  104. - [ ] Repeat on PROD with the PROD report URL.
  105. ## Notes
  106. - Reporting is Chromium-only (Chrome / Edge). Safari and Firefox still enforce
  107. `()` and usually send nothing.
  108. - Reports are batched and may arrive a few seconds after the violation, not on
  109. the same page request.
  110. - Same-origin `/api/csp-report` needs no extra CORS setup. The endpoint is
  111. already unauthenticated and CSRF is disabled.
  112. - Do not allowlist a feature in `Permissions-Policy` just to silence a report.
  113. Only grant a feature if the application itself needs it.