Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 

5.6 KiB

Permissions-Policy reporting (Apache)

The live Permissions-Policy header denies features with an empty allowlist (feature=() — grant to nobody). That header does not send reports by itself.

Unlike CSP, Permissions-Policy has no report-uri. Reporting uses the Reporting API: a named endpoint in Reporting-Endpoints, plus a per-feature report-to parameter.

Reuse the existing CSP collector:

  • UAT: https://pnspsuat.gld.gov.hk/api/csp-report
  • PROD: https://pnsps.gld.gov.hk/api/csp-report

Backend: CspReportController (POST /csp-report) already logs the raw JSON and Content-Type and returns 204. No backend change is required.

See also: csp-apache.conf.md

Why not report-uri

This CSP-style trailer does not produce Permissions-Policy reports:

# Wrong — browsers ignore report-uri on Permissions-Policy
Header always set Permissions-Policy "camera=(), geolocation=(); report-uri https://pnspsuat.gld.gov.hk/api/csp-report"

report-to is a parameter of each feature, not a global trailing directive.

Does every feature need report-to?

Yes, if you want a report for that feature.

  • feature=() — still blocked, but silent (no report)
  • feature=();report-to=csp-endpoint — blocked and reported

There is no all=() reporter and no header-level report-to that applies to every feature. Add ;report-to=csp-endpoint only on features you want in the log. Leave the rest as () if you do not need those reports.

# camera is reported; geolocation is still blocked, but not reported
Header always set Permissions-Policy "camera=();report-to=csp-endpoint, geolocation=()"

Enforcing + reporting

Keep the current deny-all policy. Add Reporting-Endpoints, then append ;report-to=csp-endpoint on each feature you want to monitor.

Copy the feature list from the live header; only the report-to parameter is new. Example (UAT):

Header always set Reporting-Endpoints "csp-endpoint=\"https://pnspsuat.gld.gov.hk/api/csp-report\""

Header always set Permissions-Policy "\
	accelerometer=();report-to=csp-endpoint, \
	autoplay=();report-to=csp-endpoint, \
	camera=();report-to=csp-endpoint, \
	display-capture=();report-to=csp-endpoint, \
	encrypted-media=();report-to=csp-endpoint, \
	fullscreen=();report-to=csp-endpoint, \
	geolocation=();report-to=csp-endpoint, \
	gyroscope=();report-to=csp-endpoint, \
	magnetometer=();report-to=csp-endpoint, \
	microphone=();report-to=csp-endpoint, \
	midi=();report-to=csp-endpoint, \
	payment=();report-to=csp-endpoint, \
	picture-in-picture=();report-to=csp-endpoint, \
	publickey-credentials-get=();report-to=csp-endpoint, \
	screen-wake-lock=();report-to=csp-endpoint, \
	usb=();report-to=csp-endpoint, \
	web-share=();report-to=csp-endpoint, \
	xr-spatial-tracking=();report-to=csp-endpoint"

PROD: same headers, with

https://pnsps.gld.gov.hk/api/csp-report

Because deny-all is already enforced, put report-to on Permissions-Policy (not only Report-Only). Those reports have disposition: "enforce".

Report-Only (observe without blocking)

Use Permissions-Policy-Report-Only only when testing a restriction that is not already denied by the enforcing header. Reports have disposition: "report".

Header always set Reporting-Endpoints "csp-endpoint=\"https://pnspsuat.gld.gov.hk/api/csp-report\""
Header always set Permissions-Policy-Report-Only "geolocation=();report-to=csp-endpoint"

Report-Only cannot re-enable a feature already denied by Permissions-Policy.

Same URL, different payload

Keep CSP on report-uri as it is. The collector URL is shared; the body is not.

Source Content-Type Body
CSP report-uri application/csp-report { "csp-report": { … } }
Permissions-Policy application/reports+json JSON array, type = permissions-policy-violation

Example Permissions-Policy report:

[{
  "type": "permissions-policy-violation",
  "url": "https://pnspsuat.gld.gov.hk/",
  "body": {
    "disposition": "enforce",
    "featureId": "geolocation",
    "message": "Permissions policy violation: geolocation access has been blocked because of a permissions policy applied to the current document."
  }
}]

Chrome often serializes the feature as policyId instead of featureId. Filter logs on permissions-policy-violation vs csp-report so the two streams stay distinct.

Optional: also point CSP at the same named endpoint (CSP report-uri remains for older browsers):

Header always set Content-Security-Policy-Report-Only "…; report-uri https://pnspsuat.gld.gov.hk/api/csp-report; report-to csp-endpoint"

Follow-up checklist

Notes

  • Reporting is Chromium-only (Chrome / Edge). Safari and Firefox still enforce () and usually send nothing.
  • Reports are batched and may arrive a few seconds after the violation, not on the same page request.
  • Same-origin /api/csp-report needs no extra CORS setup. The endpoint is already unauthenticated and CSRF is disabled.
  • Do not allowlist a feature in Permissions-Policy just to silence a report. Only grant a feature if the application itself needs it.