mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-11-15 17:46:28 +00:00
CSP (Safari-safe): merge -elem/-attr into base; respect explicit disables; no mirror-back; header only for documents/workers
- Add CSP3 support for style/script: include -elem and -attr directives - Base (style-src, script-src) now unions elem/attr (CSP2/Safari fallback) - Respect explicit base disables (e.g. style-src.unsafe-inline: false) - Hashes only when 'unsafe-inline' absent in the final base tokens - Nginx: set CSP only for HTML/worker via header_filter_by_lua_block; drop for subresources - Remove per-location header_filter; keep body_filter only - Update app role flags to *-attr where appropriate; extend desktop CSS sources - Add comprehensive unit tests for union/explicit-disable/no-mirror-back Ref: https://chatgpt.com/share/68f87a0a-cebc-800f-bb3e-8c8ab4dee8ee
This commit is contained in:
@@ -10,17 +10,6 @@
|
||||
|
||||
lua_need_request_body on;
|
||||
|
||||
header_filter_by_lua_block {
|
||||
local ct = ngx.header.content_type or ""
|
||||
if ct:lower():find("^text/html") then
|
||||
ngx.ctx.is_html = true
|
||||
-- IMPORTANT: body will be modified → drop Content-Length to avoid mismatches
|
||||
ngx.header.content_length = nil
|
||||
else
|
||||
ngx.ctx.is_html = false
|
||||
end
|
||||
}
|
||||
|
||||
body_filter_by_lua_block {
|
||||
-- Only process HTML responses
|
||||
if not ngx.ctx.is_html then
|
||||
|
||||
@@ -1,2 +1,33 @@
|
||||
add_header Content-Security-Policy "{{ applications | build_csp_header(application_id, domains) }}" always;
|
||||
proxy_hide_header Content-Security-Policy; # Todo: Make this optional
|
||||
# ===== Content Security Policy: only for documents and workers (no locations needed) =====
|
||||
|
||||
# 1) Define your CSP once (Jinja: escape double quotes to be safe)
|
||||
set $csp "{{ applications | build_csp_header(application_id, domains) | replace('\"','\\\"') }}";
|
||||
|
||||
# 2) Send CSP ONLY for document responses; also for workers via Sec-Fetch-Dest
|
||||
header_filter_by_lua_block {
|
||||
local ct = ngx.header.content_type or ngx.header["Content-Type"] or ""
|
||||
local dest = ngx.var.http_sec_fetch_dest or ""
|
||||
|
||||
local lct = ct:lower()
|
||||
local is_html = lct:find("^text/html") or lct:find("^application/xhtml+xml")
|
||||
local is_worker = (dest == "worker") or (dest == "serviceworker")
|
||||
|
||||
if is_html or is_worker then
|
||||
ngx.header["Content-Security-Policy"] = ngx.var.csp
|
||||
else
|
||||
ngx.header["Content-Security-Policy"] = nil
|
||||
ngx.header["Content-Security-Policy-Report-Only"] = nil
|
||||
end
|
||||
|
||||
-- If you'll modify the body later, drop Content-Length on HTML
|
||||
if is_html then
|
||||
ngx.ctx.is_html = true
|
||||
ngx.header.content_length = nil
|
||||
else
|
||||
ngx.ctx.is_html = false
|
||||
end
|
||||
}
|
||||
|
||||
# 3) Prevent upstream/app CSP (duplicates)
|
||||
proxy_hide_header Content-Security-Policy;
|
||||
proxy_hide_header Content-Security-Policy-Report-Only;
|
||||
|
||||
@@ -18,10 +18,10 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
font-src:
|
||||
|
||||
@@ -37,5 +37,5 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
@@ -13,7 +13,7 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
domains:
|
||||
canonical:
|
||||
|
||||
@@ -27,7 +27,7 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
domains:
|
||||
canonical:
|
||||
|
||||
@@ -29,7 +29,7 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
domains:
|
||||
canonical:
|
||||
|
||||
@@ -15,6 +15,8 @@ server:
|
||||
- https://code.jquery.com/
|
||||
style-src-elem:
|
||||
- https://cdn.jsdelivr.net
|
||||
- https://kit.fontawesome.com
|
||||
- https://code.jquery.com/
|
||||
font-src:
|
||||
- https://ka-f.fontawesome.com
|
||||
- https://cdn.jsdelivr.net
|
||||
@@ -25,7 +27,7 @@ server:
|
||||
frame-src:
|
||||
- "{{ WEB_PROTOCOL }}://*.{{ PRIMARY_DOMAIN }}"
|
||||
flags:
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
domains:
|
||||
canonical:
|
||||
|
||||
@@ -10,7 +10,7 @@ features:
|
||||
server:
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
|
||||
@@ -12,9 +12,7 @@ server:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
whitelist:
|
||||
connect-src:
|
||||
|
||||
@@ -18,10 +18,10 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
oauth2_proxy:
|
||||
application: "application"
|
||||
|
||||
@@ -27,7 +27,7 @@ server:
|
||||
aliases: []
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
font-src:
|
||||
|
||||
@@ -24,7 +24,7 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
font-src:
|
||||
|
||||
@@ -29,7 +29,7 @@ server:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
domains:
|
||||
|
||||
@@ -14,7 +14,7 @@ server:
|
||||
aliases: []
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
|
||||
@@ -19,9 +19,9 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
frame-src:
|
||||
|
||||
@@ -18,12 +18,12 @@ features:
|
||||
server:
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
domains:
|
||||
aliases: []
|
||||
|
||||
@@ -16,11 +16,11 @@ server:
|
||||
aliases: []
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
rbac:
|
||||
|
||||
@@ -17,12 +17,12 @@ server:
|
||||
style-src-elem:
|
||||
- https://fonts.googleapis.com
|
||||
flags:
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
domains:
|
||||
|
||||
@@ -27,12 +27,12 @@ features:
|
||||
server:
|
||||
csp:
|
||||
flags:
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
connect-src:
|
||||
|
||||
@@ -29,7 +29,7 @@ server:
|
||||
frame-ancestors:
|
||||
- "*" # No damage if it's used somewhere on other websites, it anyhow looks like art
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
domains:
|
||||
canonical:
|
||||
|
||||
@@ -26,11 +26,11 @@ server:
|
||||
font-src: []
|
||||
frame-ancestors: []
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
domains:
|
||||
canonical:
|
||||
|
||||
@@ -10,7 +10,7 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
domains:
|
||||
canonical:
|
||||
|
||||
@@ -12,9 +12,9 @@ server:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
whitelist:
|
||||
|
||||
@@ -19,9 +19,9 @@ server:
|
||||
# Makes sense that all of the website content is available in the navigator
|
||||
- "{{ WEB_PROTOCOL }}://*.{{ PRIMARY_DOMAIN }}"
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
|
||||
@@ -2,11 +2,11 @@ version: "production" # @see https://nextcloud.com/blog/nex
|
||||
server:
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
whitelist:
|
||||
font-src:
|
||||
|
||||
@@ -23,7 +23,7 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
font-src:
|
||||
|
||||
@@ -17,11 +17,6 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
#script-src:
|
||||
# unsafe-inline: true
|
||||
# unsafe-eval: true
|
||||
#style-src:
|
||||
# unsafe-inline: true
|
||||
whitelist:
|
||||
font-src: []
|
||||
connect-src: []
|
||||
|
||||
@@ -10,9 +10,9 @@ server:
|
||||
flags:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
frame-ancestors:
|
||||
|
||||
@@ -16,7 +16,7 @@ features:
|
||||
server:
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
|
||||
@@ -15,7 +15,7 @@ features:
|
||||
server:
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
|
||||
@@ -9,13 +9,13 @@ features:
|
||||
server:
|
||||
csp:
|
||||
flags:
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
frame-ancestors:
|
||||
|
||||
@@ -13,12 +13,12 @@ server:
|
||||
aliases: []
|
||||
csp:
|
||||
flags:
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
whitelist:
|
||||
font-src:
|
||||
|
||||
@@ -6,12 +6,12 @@ features:
|
||||
server:
|
||||
csp:
|
||||
flags:
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
domains:
|
||||
canonical:
|
||||
|
||||
@@ -69,9 +69,9 @@ server:
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
unsafe-eval: true
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
domains:
|
||||
canonical:
|
||||
|
||||
@@ -17,11 +17,11 @@ features:
|
||||
server:
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
whitelist:
|
||||
worker-src:
|
||||
|
||||
@@ -32,7 +32,7 @@ server:
|
||||
worker-src:
|
||||
- "blob:"
|
||||
flags:
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-eval: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
|
||||
@@ -20,11 +20,11 @@ server:
|
||||
aliases: []
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
script-src:
|
||||
script-src-attr:
|
||||
unsafe-inline: true
|
||||
locations:
|
||||
admin: "/admin/"
|
||||
|
||||
@@ -8,7 +8,7 @@ server:
|
||||
frame-ancestors:
|
||||
- "{{ WEB_PROTOCOL }}://*.{{ PRIMARY_DOMAIN }}"
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
docker:
|
||||
services:
|
||||
|
||||
@@ -11,7 +11,7 @@ server:
|
||||
aliases: []
|
||||
csp:
|
||||
flags:
|
||||
style-src:
|
||||
style-src-attr:
|
||||
unsafe-inline: true
|
||||
script-src-elem:
|
||||
unsafe-inline: true
|
||||
|
||||
Reference in New Issue
Block a user