Files
msos/.htaccess
T
popovskikandClaude Opus 4.8 168e4ce378 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>
2026-08-03 23:56:48 +02:00

88 lines
4.2 KiB
ApacheConf

RewriteEngine on
# ----- 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]
# ============================================================
# Static-site defaults (added for SEO / performance / 404).
# Wrapped in <IfModule> guards so a missing module can't 500.
# Ignored by nginx (harmless). No extra HTTPS/host redirects —
# the host handles TLS and the rule above handles the root.
# ============================================================
# ----- Custom branded error page -----
ErrorDocument 404 /404.html
# ----- Don't expose directory listings -----
Options -Indexes
# ----- Correct MIME types (WebP, SVG, manifest, fonts) -----
<IfModule mod_mime.c>
AddType image/webp .webp
AddType image/svg+xml .svg
AddType application/manifest+json .webmanifest
AddType image/x-icon .ico
AddType font/woff2 .woff2
</IfModule>
# ----- Gzip / compression for text assets -----
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE application/xml application/manifest+json
AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
# ----- Browser caching -----
# No file-hashing on this site, so keep CSS/JS short (updates must propagate)
# and cache images/fonts longer. HTML is always revalidated.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 1 day"
ExpiresByType application/javascript "access plus 1 day"
ExpiresByType image/webp "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 month"
ExpiresByType font/woff2 "access plus 1 month"
</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>
</IfModule>