| @@ -50,7 +50,7 @@ map $sent_http_content_type $x_frame_options { |
| 50 | 50 | # literal newlines, which nginx emitted verbatim -- a folded, malformed header |
| 51 | 51 | # that clients saw as empty. Policies must be ONE line. |
| 52 | 52 | map $sent_http_content_type $content_security_policy { |
| 53 | | ~*text/(html|javascript)|application/pdf|xml "default-src 'self'; img-src 'self' data:; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'; upgrade-insecure-requests"; |
| 53 | ~*text/(html|javascript)|application/pdf|xml "default-src 'self'; img-src 'self' data:; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'"; |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | 56 | # cleberg.* only. Mirrors what the site actually loads, verified by grepping |
| @@ -69,6 +69,23 @@ map $sent_http_content_type $content_security_policy_cmc { |
| 69 | 69 | ~*text/(html|javascript)|application/pdf|xml "default-src 'self'; img-src 'self' https://img.cleberg.net data:; script-src 'self' https://bubbles.town; connect-src 'self' https://bubbles.town; style-src 'self' https://cleberg.net; font-src 'self' https://cleberg.net; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'"; |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | # krz.sh only. Derived from the served HTML after the img.cleberg.net removal |
| 73 | # (2026-08-03), counted with an HTML parser: |
| 74 | # 14 <img src> -> https://i.krz.sh (the new krz-side image host) |
| 75 | # 12 <link rel=stylesheet> -> https://krz.sh (ABSOLUTE, not relative) |
| 76 | # 12 <link rel=icon> -> https://krz.sh (covered by img-src) |
| 77 | # 0 scripts, inline or external; 0 inline styles. |
| 78 | # |
| 79 | # `https://krz.sh` is listed explicitly because those URLs are absolute: on a |
| 80 | # future krz.sh onion they would be cross-origin and 'self' would block them. |
| 81 | # Same reasoning as the cmc policy above. |
| 82 | # |
| 83 | # script-src stays 'self' rather than 'none': the site ships no scripts today, |
| 84 | # but 'none' would break the first one added, in a way that is easy to misread. |
| 85 | map $sent_http_content_type $content_security_policy_krz { |
| 86 | ~*text/(html|javascript)|application/pdf|xml "default-src 'self'; img-src 'self' https://krz.sh https://i.krz.sh data:; style-src 'self' https://krz.sh; font-src 'self' https://krz.sh; script-src 'self'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'"; |
| 87 | } |
| 88 | |
| 72 | 89 | # For apps that ship inline <script>/<style>/style="" and cannot use the strict |
| 73 | 90 | # policy. Currently only office.zerolabs.sh (5 files with inline <script>, |
| 74 | 91 | # 3 with <style>, 2 with style attributes). Identity-neutral -- no host is |
| @@ -79,7 +96,7 @@ map $sent_http_content_type $content_security_policy_cmc { |
| 79 | 96 | # strictly worse. The upgrade path is per-file hashes or nonces; that needs |
| 80 | 97 | # changes to the app, not to nginx. |
| 81 | 98 | map $sent_http_content_type $content_security_policy_inline { |
| 82 | | ~*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'; upgrade-insecure-requests"; |
| 99 | ~*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'"; |
| 83 | 100 | } |
| 84 | 101 | |
| 85 | 102 | # --- Proxied third-party apps ------------------------------------------- |