security: harden static site (headers, exposed-file cleanup, privacy)
Proactive security & health pass. No live/exploitable vulnerabilities were found; these changes remove information-disclosure surfaces and add standard hardening. - Remove publicly-downloadable 1.1 MB full source dump (code_export.txt) and stray empty l.php; add code_export.txt to .gitignore. - Exclude dev files/folders (*.sh, *.py, docs/, templates/, tools/, README.md) from the rsync deploy so they never reach the live server. - .htaccess: add X-Frame-Options, Referrer-Policy, Permissions-Policy, and a report-only Content-Security-Policy; add defense-in-depth deny block for dev/VCS files (robots.txt & sitemap.xml left served). - .htaccess: fix root redirect to canonical msosorg.com + /en/. - Swap 4 project-page YouTube embeds to youtube-nocookie.com so no Google cookies are set before consent (GDPR). - Add rel="noopener" to 30 team social links on the About Us pages. - Harden esc() in my-route.js to also escape single quotes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
c2b1b6eb5a
commit
168e4ce378
13 files changed
+75
-22777
No files matched your search
@@ -1,8 +1,28 @@
|
||||
|
||||
RewriteEngine on
|
||||
RewriteCond %{HTTP_HOST} ^msos\.spletnimojster\.si$ [OR]
|
||||
RewriteCond %{HTTP_HOST} ^www\.msos\.spletnimojster\.si$
|
||||
RewriteRule ^/?$ "https\:\/\/msos\.spletnimojster\.si\/en\/" [R=301,L]
|
||||
|
||||
# ----- Canonical domain + language root -----
|
||||
# Migrate the old host to the canonical domain, preserving the path.
|
||||
RewriteCond %{HTTP_HOST} ^(www\.)?msos\.spletnimojster\.si$ [NC]
|
||||
RewriteRule ^ https://msosorg.com%{REQUEST_URI} [R=301,L]
|
||||
# Send the bare root to the default-language homepage.
|
||||
RewriteRule ^/?$ https://msosorg.com/en/ [R=301,L]
|
||||
|
||||
# ----- Defense-in-depth: block dev/sensitive files if they ever ship -----
|
||||
# (The deploy already excludes these; this is a safety net. robots.txt,
|
||||
# sitemap.xml and site.webmanifest are intentionally NOT blocked.)
|
||||
<FilesMatch "(?i)(^code_export\.txt$|\.(sh|py|php|bak|old|log|ini|sql|yml|yaml)$)">
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
# Block internal folders and VCS/CI dirs.
|
||||
RewriteRule (^|/)\.(git|gitea)(/|$) - [F,L]
|
||||
RewriteRule ^(docs|templates|tools)(/|$) - [F,L]
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -52,6 +72,15 @@ Options -Indexes
|
||||
</IfModule>
|
||||
<IfModule mod_headers.c>
|
||||
Header set X-Content-Type-Options "nosniff"
|
||||
# Clickjacking protection — the site should never be framed by other origins.
|
||||
Header always set X-Frame-Options "SAMEORIGIN"
|
||||
# Don't leak full page URLs to third parties (analytics, external links).
|
||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
# Explicitly disable browser features the site doesn't use.
|
||||
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"
|
||||
# Content-Security-Policy in REPORT-ONLY first so it cannot break styling/scripts.
|
||||
# Review browser console for violations, tighten, then switch to Content-Security-Policy.
|
||||
Header always set Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' https://www.googletagmanager.com; connect-src 'self' https://www.google-analytics.com https://region1.google-analytics.com; frame-src https://www.youtube-nocookie.com https://www.youtube.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self' https://docs.google.com"
|
||||
<FilesMatch "\.html$">
|
||||
Header set Cache-Control "no-cache, must-revalidate"
|
||||
</FilesMatch>
|
||||
|
||||
Reference in new issue
Block a user