diff options
Diffstat (limited to 'linux')
4 files changed, 14 insertions, 52 deletions
diff --git a/linux/nginx/etc/nginx/conf.d/rss.conf b/linux/nginx/etc/nginx/conf.d/rss.conf deleted file mode 100644 index 963950f..0000000 --- a/linux/nginx/etc/nginx/conf.d/rss.conf +++ /dev/null @@ -1,31 +0,0 @@ -upstream freshrss { server 127.0.0.1:8099; keepalive 64; } -server { - listen 127.0.0.1:10045; - server_name rss.zerolabs.sh; - - include custom.d/basic.conf; - location / { - proxy_pass http://freshrss/; - # This add_header discarded EVERYTHING from basic.conf -- nginx does - # not merge add_header across levels. Verified: this vhost was serving - # X-Frame-Options and nothing else (no Referrer-Policy, no HSTS, no - # Permissions-Policy, no X-Content-Type-Options). Restored below. - # SAMEORIGIN (not the shared map's DENY) -- hence the _no_xfo bundle, - # which omits X-Frame-Options so the two do not conflict. - add_header X-Frame-Options SAMEORIGIN; - include custom.d/security/headers_in_location_no_xfo.conf; - include custom.d/security/content-security-policy-freshrss-report-only.conf; - proxy_redirect off; - proxy_buffering off; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Port $server_port; - proxy_read_timeout 90; - proxy_set_header Authorization $http_authorization; - proxy_pass_header Authorization; - } - include custom.d/security/robots_index_only.conf; -} - diff --git a/linux/nginx/etc/nginx/custom.d/http/content_type_maps.conf b/linux/nginx/etc/nginx/custom.d/http/content_type_maps.conf index b27cbf0..f8a5e84 100644 --- a/linux/nginx/etc/nginx/custom.d/http/content_type_maps.conf +++ b/linux/nginx/etc/nginx/custom.d/http/content_type_maps.conf @@ -99,13 +99,19 @@ map $sent_http_content_type $content_security_policy_inline { ~*text/(html|javascript)|application/pdf|xml "default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'"; } -# --- Proxied third-party apps ------------------------------------------- -# These two are shipped REPORT-ONLY (see the *-report-only.conf includes). -# Both are third-party SPAs whose runtime behaviour cannot be exercised from -# the shell -- no browser here -- and a wrong directive fails SILENTLY: video -# stops playing, or every article image disappears, with only a console -# message. Report-Only gives the visibility with zero outage risk. Promote to -# enforcing after checking a real browser console. +# --- Proxied third-party app --------------------------------------------- +# Shipped Report-Only first, then PROMOTED TO ENFORCING 2026-08-03 after a real +# browser validated it: homepage, VOD playback + seek on two videos, channel +# page, and a 39-result search were all clean, and every host contacted was +# already in the policy (self, pipedapi, pipedproxy, blob:). +# +# The check was proven meaningful before being believed: a deliberately +# disallowed image was injected and fired a securitypolicyviolation with +# disposition "report", confirming the header was live rather than absent. +# +# (A FreshRSS policy lived here too. It was removed -- rss.krz.sh is routed +# tunnel-direct to the container and never transits nginx, so the header never +# reached a browser. FreshRSS enforces its own, correctly RSS-aware, CSP.) # piped.krz.sh. Derived from evidence, not guesswork: # - connect-src: BACKEND_HOSTNAME=pipedapi.krz.sh (container env). @@ -121,15 +127,6 @@ map $sent_http_content_type $csp_piped { ~*text/(html|javascript)|application/pdf|xml "default-src 'self'; connect-src 'self' https://pipedapi.krz.sh; img-src 'self' https://pipedproxy.krz.sh data: blob:; media-src 'self' https://pipedproxy.krz.sh blob:; script-src 'self' 'unsafe-inline' data:; style-src 'self' 'unsafe-inline'; worker-src 'self' blob:; font-src 'self' data:; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'"; } -# rss.zerolabs.sh (FreshRSS). Operator-only behind Cloudflare Access, so the -# T5 stake is low; the risk is breakage. An RSS reader renders arbitrary feed -# HTML, so img/media must allow remote hosts or every article image dies. -# That remote fetching is inherent to the app and is controlled by FreshRSS's -# own "load remote images" setting, not by CSP. -map $sent_http_content_type $csp_freshrss { - ~*text/(html|javascript)|application/pdf|xml "default-src 'self'; img-src 'self' https: data:; media-src 'self' https:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; frame-src https:; base-uri 'none'; form-action 'self'; frame-ancestors 'self'; object-src 'none'"; -} - # Permissions-Policy variant for media apps. The shared policy sets # `fullscreen=()`, which is exactly why piped.conf excludes basic.conf -- it # would stop videos going fullscreen. This keeps every other restriction and diff --git a/linux/nginx/etc/nginx/custom.d/security/content-security-policy-freshrss-report-only.conf b/linux/nginx/etc/nginx/custom.d/security/content-security-policy-freshrss-report-only.conf deleted file mode 100644 index bff2fd5..0000000 --- a/linux/nginx/etc/nginx/custom.d/security/content-security-policy-freshrss-report-only.conf +++ /dev/null @@ -1,4 +0,0 @@ -# rss.zerolabs.sh -- REPORT-ONLY. See the note in content_type_maps.conf: -# the authenticated reading view cannot be exercised from the shell, and a -# wrong img-src silently removes every article image. -add_header Content-Security-Policy-Report-Only $csp_freshrss always; diff --git a/linux/nginx/etc/nginx/custom.d/security/content-security-policy-piped-report-only.conf b/linux/nginx/etc/nginx/custom.d/security/content-security-policy-piped-report-only.conf index 5c76cd5..24917aa 100644 --- a/linux/nginx/etc/nginx/custom.d/security/content-security-policy-piped-report-only.conf +++ b/linux/nginx/etc/nginx/custom.d/security/content-security-policy-piped-report-only.conf @@ -2,4 +2,4 @@ # nothing is blocked. Promote to enforcing (rename the header to # Content-Security-Policy) only after loading a video, seeking, going # fullscreen and opening a channel page with a real browser console open. -add_header Content-Security-Policy-Report-Only $csp_piped always; +add_header Content-Security-Policy $csp_piped always; |
