# Security Rules for UK Data Services
# Protect sensitive files and configs
Require all denied
# Protect contact handlers from direct browser access (POST only)
Require all denied
Require all denied
# Security headers
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=()"
# CRITICAL: No caching for form pages (contain session-specific CSRF tokens)
Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
Header set Pragma "no-cache"
Header set Expires "Sat, 01 Jan 2000 00:00:00 GMT"
# Enhanced Gzip compression
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
AddOutputFilterByType DEFLATE application/javascript application/x-javascript
AddOutputFilterByType DEFLATE application/xml application/xhtml+xml application/rss+xml
AddOutputFilterByType DEFLATE application/json application/ld+json
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE font/ttf font/otf font/eot font/woff font/woff2
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
Header append Vary User-Agent
# Enable Brotli compression if available
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript
AddOutputFilterByType BROTLI_COMPRESS application/javascript application/x-javascript
AddOutputFilterByType BROTLI_COMPRESS application/xml application/xhtml+xml application/rss+xml
AddOutputFilterByType BROTLI_COMPRESS application/json application/ld+json
AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
AddOutputFilterByType BROTLI_COMPRESS font/ttf font/otf font/woff font/woff2
# Browser Caching Headers
ExpiresActive On
# Images - 1 year
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType image/ico "access plus 1 year"
# Fonts - 1 year
ExpiresByType font/ttf "access plus 1 year"
ExpiresByType font/otf "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType application/font-woff "access plus 1 year"
ExpiresByType application/font-woff2 "access plus 1 year"
# CSS and JavaScript - 1 month
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
# HTML and PHP - 1 hour
ExpiresByType text/html "access plus 1 hour"
ExpiresByType application/xhtml+xml "access plus 1 hour"
# Data - no cache
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"
# Default - 1 week
ExpiresDefault "access plus 1 week"
# Cache-Control Headers
# Static assets - 1 year
Header set Cache-Control "max-age=31536000, public, immutable"
# CSS and JS - 1 month
Header set Cache-Control "max-age=2592000, public"
# Regular HTML/PHP - 1 hour (but form pages are excluded above)
Header set Cache-Control "max-age=3600, public, must-revalidate"
# Keep-alive
Header set Connection keep-alive
# HTTP/2 Server Push
Header add Link "; rel=preload; as=style"
Header add Link "; rel=preload; as=image"
Header add Link "; rel=preload; as=script"
# ETags
FileETag None
Header unset ETag
# Disable directory browsing
Options -Indexes
# Prevent access to logs and database directories
RewriteEngine On
# Skip already processed .php files
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^services/.*\.php$ - [L]
# Explicitly allow existing service pages
RewriteRule ^services/competitive-intelligence/?$ /services/competitive-intelligence.php [L]
RewriteRule ^services/data-cleaning/?$ /services/data-cleaning.php [L]
RewriteRule ^services/financial-data-services/?$ /services/financial-data-services.php [L]
RewriteRule ^services/price-monitoring/?$ /services/price-monitoring.php [L]
RewriteRule ^services/property-data-extraction/?$ /services/property-data-extraction.php [L]
RewriteRule ^services/web-scraping/?$ /services/web-scraping.php [L]
# Redirect /services index to project-types
RewriteRule ^services/?$ /project-types [R=301,L]
# Redirect unknown service pages to project-types
RewriteRule ^services/(.+)$ /project-types [R=301,L]
# Clean URL rewriting - remove .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
# Security rules
RewriteRule ^logs(/.*)?$ - [F,L]
RewriteRule ^database(/.*)?$ - [F,L]
RewriteRule ^\.git(/.*)?$ - [F,L]
RewriteRule ^docker(/.*)?$ - [F,L]
# Disable server signature
ServerSignature Off
# === Page Speed Optimizations ===
# Enable Gzip compression
AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/javascript application/json image/svg+xml
# Browser caching
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 2 days"
# Cache-Control headers
Header set Cache-Control "max-age=31536000, public"
Header set Cache-Control "max-age=600, private, must-revalidate"
# Keep-Alive
Header set Connection keep-alive