PST-093: Content security policy hardening notes: data: images, base-uri, no violation reporting #822
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#822
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found in the security audit of 2026-10-10 (
SECURITY-AUDIT-2026-10-10.md), run againstmainatc30851bfrom 8 to 10 October 2026, as PST-093. Severity: Informational.The text below is the audit's entry, unchanged apart from links to the other issues it names. The finding was produced by automated review and checked by a second automated pass; re-check it before acting on it.
src/postulo/config/settings/base.py(703-731)Who can do it, and what they need. None on its own; these only widen what an injection elsewhere could use.
How it works.
img-src data: lets injected markup draw attacker images without a request (used legitimately by the CV photo in the preview, rendering.py/printing.py:448, and by allauth's TOTP QR code, allauth/elements/img.html). base-uri 'self' is fine since no <base> element exists, but 'none' would be stricter. There is no report-to/report-uri, so a violation in production is only visible in a browser console.
Impact. Negligible; recorded so the synthesis can say the policy was reviewed. No 'unsafe-inline', no 'unsafe-eval', script-src 'self' only, style nonce reaches the header only on the two preview views that read it (documents/views.py:340-347), frame-ancestors 'none' globally and 'self' only on the previews, object-src 'none', form-action 'self', no view or plugin relaxes it (only csp_override is …
Verification (verdict: confirmed; severity after verification: Informational). Not a vulnerability. Keep it as a coverage note. The only optional improvement is base-uri 'none', which is stylistic because no <base> element exists. The report-to omission is a reasonable choice for a self-hosted, privacy-first app with no reporting endpoint. The data: allowance in img-src is needed by the CV photo and the TOTP QR code and cannot exfiltrate anything. The cite printing.py:448 is correct.
Suggested remediation. Consider base-uri 'none', a report-to endpoint (even a log-only view) so production violations are seen, and keep data: images confined to the preview responses via a csp_override if the photo and the QR code are the only users.
Fixed in
d7ca1b02bon main.