# ============================================================ # Performance & Security Rules # Based on: Core Web Vitals, Lighthouse, OWASP, Mozilla Observatory # ============================================================ metadata: name: "Performance & Security Standards" version: "1.0.0" last_updated: "2026-02-13" sources: - name: "Google Core Web Vitals" url: "https://developers.google.com/search/docs/appearance/core-web-vitals" - name: "Lighthouse Performance Audits" url: "https://developer.chrome.com/docs/lighthouse/performance/" - name: "OWASP Secure Headers Project" url: "https://owasp.org/www-project-secure-headers/" - name: "OWASP HTTP Headers Cheat Sheet" url: "https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html" - name: "Mozilla Observatory" url: "https://observatory.mozilla.org/" - name: "OWASP Top 10 (2021)" url: "https://owasp.org/www-project-top-ten/" # ============================================================ # PERFORMANCE RULES # ============================================================ performance: # --- Core Web Vitals --- core_web_vitals: - id: "perf-lcp" name: "Largest Contentful Paint (LCP)" description: "Measures loading performance - time to render the largest content element" severity: "critical" category: "loading" standard: "Google Core Web Vitals" thresholds: good: 2500 # ms needs_improvement: 4000 poor: 4001 # above this unit: "milliseconds" tips: - "Optimize and compress images (WebP/AVIF format)" - "Preload critical resources" - "Remove render-blocking resources" - "Use a CDN for static assets" - "Optimize server response time (TTFB < 800ms)" - id: "perf-inp" name: "Interaction to Next Paint (INP)" description: "Measures responsiveness - latency of all user interactions" severity: "critical" category: "interactivity" standard: "Google Core Web Vitals" note: "Replaced FID (First Input Delay) in March 2024" thresholds: good: 200 # ms needs_improvement: 500 poor: 501 unit: "milliseconds" tips: - "Break up long tasks (> 50ms)" - "Reduce JavaScript execution time" - "Use web workers for heavy computation" - "Minimize main thread work" - "Optimize event handlers" - id: "perf-cls" name: "Cumulative Layout Shift (CLS)" description: "Measures visual stability - unexpected layout shifts during page life" severity: "critical" category: "visual_stability" standard: "Google Core Web Vitals" thresholds: good: 0.1 needs_improvement: 0.25 poor: 0.26 unit: "score" tips: - "Set explicit width/height on images and video" - "Reserve space for ads and embeds" - "Avoid inserting content above existing content" - "Use CSS contain for dynamic content" - "Preload web fonts and use font-display: swap" # --- Additional Performance Metrics --- additional_metrics: - id: "perf-fcp" name: "First Contentful Paint (FCP)" description: "Time to render the first piece of DOM content" severity: "major" category: "loading" standard: "Lighthouse" thresholds: good: 1800 # ms needs_improvement: 3000 poor: 3001 unit: "milliseconds" - id: "perf-ttfb" name: "Time to First Byte (TTFB)" description: "Time from request to first byte of response" severity: "major" category: "server" standard: "Lighthouse" thresholds: good: 800 # ms needs_improvement: 1800 poor: 1801 unit: "milliseconds" tips: - "Use a CDN" - "Optimize server-side rendering" - "Enable HTTP/2 or HTTP/3" - "Optimize database queries" - id: "perf-si" name: "Speed Index" description: "How quickly content is visually displayed during page load" severity: "major" category: "loading" standard: "Lighthouse" thresholds: good: 3400 # ms needs_improvement: 5800 poor: 5801 unit: "milliseconds" - id: "perf-tbt" name: "Total Blocking Time (TBT)" description: "Total time where main thread was blocked for > 50ms between FCP and TTI" severity: "major" category: "interactivity" standard: "Lighthouse" thresholds: good: 200 # ms needs_improvement: 600 poor: 601 unit: "milliseconds" # --- Resource Optimization --- resource_checks: - id: "perf-total-page-size" name: "Total Page Size" description: "Total size of all resources loaded by the page" severity: "major" category: "resources" standard: "Web Performance Best Practice" thresholds: good: 1500 # KB needs_improvement: 3000 poor: 5000 unit: "kilobytes" - id: "perf-total-requests" name: "Total HTTP Requests" description: "Total number of HTTP requests made by the page" severity: "major" category: "resources" standard: "Web Performance Best Practice" thresholds: good: 50 needs_improvement: 80 poor: 100 unit: "count" - id: "perf-image-optimization" name: "Image Optimization" description: "Images should be properly optimized" severity: "major" category: "resources" standard: "Lighthouse" checks: - id: "uses-webp-avif" description: "Use modern image formats (WebP, AVIF)" severity: "minor" - id: "responsive-images" description: "Use srcset for responsive images" severity: "minor" - id: "lazy-loading" description: "Offscreen images should use lazy loading" severity: "minor" - id: "image-dimensions" description: "Images should have explicit width and height" severity: "major" - id: "oversized-images" description: "Images should not be larger than their display size" severity: "minor" - id: "perf-js-optimization" name: "JavaScript Optimization" description: "JavaScript should be properly optimized" severity: "major" category: "resources" standard: "Lighthouse" checks: - id: "minified-js" description: "JavaScript should be minified" severity: "minor" - id: "no-render-blocking-js" description: "Non-critical JS should use async or defer" severity: "major" - id: "unused-js" description: "Remove unused JavaScript" severity: "minor" - id: "js-bundle-size" description: "Individual JS bundles should be under 250KB (compressed)" max_size_kb: 250 severity: "major" - id: "perf-css-optimization" name: "CSS Optimization" description: "CSS should be properly optimized" severity: "minor" category: "resources" standard: "Lighthouse" checks: - id: "minified-css" description: "CSS should be minified" severity: "minor" - id: "no-render-blocking-css" description: "Non-critical CSS should be deferred" severity: "major" - id: "unused-css" description: "Remove unused CSS rules" severity: "minor" - id: "critical-css-inlined" description: "Critical CSS should be inlined" severity: "info" - id: "perf-font-optimization" name: "Font Optimization" description: "Web fonts should be properly optimized" severity: "minor" category: "resources" standard: "Web Performance Best Practice" checks: - id: "font-display" description: "Use font-display: swap or optional" severity: "minor" - id: "preload-fonts" description: "Preload critical fonts" severity: "minor" - id: "font-subsetting" description: "Use font subsetting for CJK fonts" severity: "info" - id: "woff2-format" description: "Use WOFF2 format for web fonts" severity: "minor" # --- Caching & Compression --- caching: - id: "perf-compression" name: "Text Compression" description: "Text resources should be served with compression" severity: "major" category: "network" standard: "Lighthouse" details: supported_encodings: - "gzip" - "br (Brotli - preferred)" - "zstd" applies_to: - "text/html" - "text/css" - "application/javascript" - "application/json" - "image/svg+xml" - id: "perf-cache-headers" name: "Cache Headers" description: "Static resources should have proper cache headers" severity: "major" category: "network" standard: "HTTP Caching (RFC 7234)" details: checks: - id: "has-cache-control" description: "Static assets should have Cache-Control header" - id: "long-cache-lifetime" description: "Static assets should have cache lifetime >= 1 year" recommended: "Cache-Control: public, max-age=31536000, immutable" - id: "etag" description: "Resources should have ETag for validation" - id: "perf-http2" name: "HTTP/2 or HTTP/3" description: "Site should use HTTP/2 or HTTP/3 protocol" severity: "minor" category: "network" standard: "IETF RFC 9113 (HTTP/2), RFC 9114 (HTTP/3)" details: description: "HTTP/2+ provides multiplexing, header compression, and server push" # ============================================================ # SECURITY RULES # ============================================================ security: # --- HTTP Security Headers (OWASP) --- headers: - id: "sec-strict-transport-security" name: "Strict-Transport-Security (HSTS)" description: "Enforces HTTPS-only access to prevent protocol downgrade attacks" severity: "critical" category: "transport" standard: "OWASP Secure Headers Project" standard_ref: "RFC 6797" check_type: "header_check" details: header: "Strict-Transport-Security" recommended_value: "max-age=63072000; includeSubDomains; preload" directives: - name: "max-age" description: "Time in seconds browser should remember HTTPS-only" recommended: 63072000 # 2 years minimum: 31536000 # 1 year - name: "includeSubDomains" description: "Apply to all subdomains" recommended: true - name: "preload" description: "Allow inclusion in browser HSTS preload list" recommended: true note: "Only effective over HTTPS connections" - id: "sec-content-security-policy" name: "Content-Security-Policy (CSP)" description: "Restricts content origins to prevent XSS and injection attacks" severity: "critical" category: "injection" standard: "OWASP Secure Headers Project" standard_ref: "W3C CSP Level 3" check_type: "header_check" details: header: "Content-Security-Policy" recommended_directives: - directive: "default-src" description: "Fallback for other directives" recommended: "'self'" - directive: "script-src" description: "Valid sources for JavaScript" recommended: "'self'" avoid: "'unsafe-inline', 'unsafe-eval'" - directive: "style-src" description: "Valid sources for stylesheets" recommended: "'self'" - directive: "img-src" description: "Valid sources for images" recommended: "'self' data:" - directive: "font-src" description: "Valid sources for fonts" recommended: "'self'" - directive: "connect-src" description: "Valid targets for XMLHttpRequest, Fetch, WebSocket" recommended: "'self'" - directive: "frame-ancestors" description: "Valid parents for embedding (replaces X-Frame-Options)" recommended: "'none'" - directive: "base-uri" description: "Restricts URLs for base element" recommended: "'self'" - directive: "form-action" description: "Restricts form submission targets" recommended: "'self'" - directive: "object-src" description: "Valid sources for plugins" recommended: "'none'" - directive: "upgrade-insecure-requests" description: "Upgrade HTTP requests to HTTPS" recommended: true - id: "sec-x-frame-options" name: "X-Frame-Options" description: "Prevents page from being displayed in frames (clickjacking protection)" severity: "critical" category: "clickjacking" standard: "OWASP Secure Headers Project" standard_ref: "RFC 7034" check_type: "header_check" details: header: "X-Frame-Options" recommended_value: "DENY" valid_values: - value: "DENY" description: "Page cannot be displayed in any frame" - value: "SAMEORIGIN" description: "Page can only be displayed in frame on same origin" note: "CSP frame-ancestors is the modern replacement" - id: "sec-x-content-type-options" name: "X-Content-Type-Options" description: "Prevents MIME type sniffing attacks" severity: "major" category: "injection" standard: "OWASP Secure Headers Project" check_type: "header_check" details: header: "X-Content-Type-Options" recommended_value: "nosniff" description: "Blocks browsers from guessing MIME types, preventing XSS via MIME confusion" - id: "sec-referrer-policy" name: "Referrer-Policy" description: "Controls referrer information sent with requests" severity: "major" category: "privacy" standard: "OWASP Secure Headers Project" standard_ref: "W3C Referrer Policy" check_type: "header_check" details: header: "Referrer-Policy" recommended_value: "strict-origin-when-cross-origin" valid_values: - value: "no-referrer" description: "Never send referrer" security: "highest" - value: "no-referrer-when-downgrade" description: "Don't send referrer on HTTPS → HTTP" security: "medium" - value: "origin" description: "Only send the origin" security: "high" - value: "origin-when-cross-origin" description: "Full URL for same-origin, origin for cross-origin" security: "medium" - value: "same-origin" description: "Only send referrer for same-origin requests" security: "high" - value: "strict-origin" description: "Send origin when protocol stays same" security: "high" - value: "strict-origin-when-cross-origin" description: "Full URL for same-origin, origin for cross-origin (same protocol)" security: "medium-high" - value: "unsafe-url" description: "Always send full URL" security: "none" - id: "sec-permissions-policy" name: "Permissions-Policy" description: "Controls browser feature access (geolocation, camera, etc.)" severity: "major" category: "privacy" standard: "OWASP Secure Headers Project" standard_ref: "W3C Permissions Policy" check_type: "header_check" details: header: "Permissions-Policy" recommended_value: "geolocation=(), camera=(), microphone=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()" controllable_features: - feature: "geolocation" description: "Access to user's location" default_recommendation: "()" # deny all - feature: "camera" description: "Access to device camera" default_recommendation: "()" - feature: "microphone" description: "Access to device microphone" default_recommendation: "()" - feature: "payment" description: "Payment Request API" default_recommendation: "()" - feature: "usb" description: "WebUSB API" default_recommendation: "()" - feature: "magnetometer" description: "Magnetometer sensor" default_recommendation: "()" - feature: "gyroscope" description: "Gyroscope sensor" default_recommendation: "()" - feature: "accelerometer" description: "Accelerometer sensor" default_recommendation: "()" - feature: "autoplay" description: "Auto-play media" default_recommendation: "(self)" - feature: "fullscreen" description: "Fullscreen API" default_recommendation: "(self)" - feature: "interest-cohort" description: "FLoC / Topics API (ad tracking)" default_recommendation: "()" - id: "sec-cross-origin-opener-policy" name: "Cross-Origin-Opener-Policy (COOP)" description: "Isolates browsing context to prevent Spectre-type attacks" severity: "minor" category: "isolation" standard: "OWASP Secure Headers Project" check_type: "header_check" details: header: "Cross-Origin-Opener-Policy" recommended_value: "same-origin" valid_values: - "unsafe-none" - "same-origin-allow-popups" - "same-origin" - id: "sec-cross-origin-embedder-policy" name: "Cross-Origin-Embedder-Policy (COEP)" description: "Restricts cross-origin resource loading" severity: "minor" category: "isolation" standard: "OWASP Secure Headers Project" check_type: "header_check" details: header: "Cross-Origin-Embedder-Policy" recommended_value: "require-corp" valid_values: - "unsafe-none" - "require-corp" - "credentialless" - id: "sec-cross-origin-resource-policy" name: "Cross-Origin-Resource-Policy (CORP)" description: "Blocks resource loading from unauthorized origins" severity: "minor" category: "isolation" standard: "OWASP Secure Headers Project" check_type: "header_check" details: header: "Cross-Origin-Resource-Policy" recommended_value: "same-site" valid_values: - "same-site" - "same-origin" - "cross-origin" # --- Headers to Remove (Information Disclosure) --- headers_to_remove: - id: "sec-remove-server" name: "Remove Server Header" description: "Server header exposes web server technology" severity: "minor" category: "information_disclosure" standard: "OWASP Secure Headers Project" details: header: "Server" action: "Remove or set to non-informative value" reason: "Prevents fingerprinting of web server software" - id: "sec-remove-x-powered-by" name: "Remove X-Powered-By Header" description: "X-Powered-By exposes application framework" severity: "minor" category: "information_disclosure" standard: "OWASP Secure Headers Project" details: header: "X-Powered-By" action: "Remove entirely" reason: "Prevents fingerprinting of application framework (Express, PHP, ASP.NET)" - id: "sec-remove-x-aspnet-version" name: "Remove X-AspNet-Version Header" description: "Exposes .NET framework version" severity: "minor" category: "information_disclosure" standard: "OWASP Secure Headers Project" details: header: "X-AspNet-Version" action: "Remove entirely" - id: "sec-remove-x-aspnetmvc-version" name: "Remove X-AspNetMvc-Version Header" description: "Exposes ASP.NET MVC version" severity: "minor" category: "information_disclosure" standard: "OWASP Secure Headers Project" details: header: "X-AspNetMvc-Version" action: "Remove entirely" # --- Deprecated Headers --- deprecated_headers: - id: "sec-no-x-xss-protection" name: "X-XSS-Protection (Deprecated)" description: "Legacy XSS filter - should be disabled in favor of CSP" severity: "info" category: "legacy" standard: "OWASP Secure Headers Project" details: header: "X-XSS-Protection" recommended_value: "0" reason: "Modern browsers have removed XSS auditor; use CSP instead" note: "Setting to 1; mode=block can introduce vulnerabilities in older browsers" - id: "sec-no-public-key-pins" name: "Public-Key-Pins (HPKP) - Removed" description: "HTTP Public Key Pinning is deprecated and should not be used" severity: "info" category: "legacy" standard: "OWASP Secure Headers Project" details: header: "Public-Key-Pins" action: "Do not use" reason: "Risk of permanent site lockout; replaced by Certificate Transparency" # --- Transport Security --- transport: - id: "sec-https" name: "HTTPS Enforcement" description: "Site must be served over HTTPS" severity: "critical" category: "transport" standard: "OWASP / Google" checks: - id: "uses-https" description: "Page is served over HTTPS" severity: "critical" - id: "no-mixed-content" description: "No HTTP resources loaded on HTTPS page" severity: "critical" - id: "http-redirects-to-https" description: "HTTP requests redirect to HTTPS" severity: "major" - id: "valid-certificate" description: "SSL/TLS certificate is valid and not expired" severity: "critical" - id: "strong-tls-version" description: "Uses TLS 1.2 or higher" severity: "major" details: minimum_version: "TLS 1.2" recommended_version: "TLS 1.3" deprecated_versions: - "SSL 2.0" - "SSL 3.0" - "TLS 1.0" - "TLS 1.1" # --- Cookie Security --- cookies: - id: "sec-cookie-secure" name: "Secure Cookie Flag" description: "Cookies should have Secure flag over HTTPS" severity: "major" category: "cookies" standard: "OWASP Session Management" details: flag: "Secure" description: "Cookie only sent over HTTPS connections" - id: "sec-cookie-httponly" name: "HttpOnly Cookie Flag" description: "Session cookies should have HttpOnly flag" severity: "major" category: "cookies" standard: "OWASP Session Management" details: flag: "HttpOnly" description: "Cookie not accessible via JavaScript (prevents XSS theft)" - id: "sec-cookie-samesite" name: "SameSite Cookie Attribute" description: "Cookies should have SameSite attribute" severity: "major" category: "cookies" standard: "OWASP Session Management" details: attribute: "SameSite" recommended_value: "Lax" valid_values: - value: "Strict" description: "Cookie not sent in any cross-site request" - value: "Lax" description: "Cookie sent in top-level navigations (recommended default)" - value: "None" description: "Cookie sent in all contexts (requires Secure flag)" # --- Content Security --- content: - id: "sec-subresource-integrity" name: "Subresource Integrity (SRI)" description: "External scripts/styles should use integrity attribute" severity: "minor" category: "supply_chain" standard: "W3C Subresource Integrity" check_type: "attribute_check" details: applies_to: - "script[src] from CDN" - "link[rel=stylesheet] from CDN" attribute: "integrity" description: "Hash-based verification of external resources" - id: "sec-form-action-https" name: "Form Action HTTPS" description: "Form actions should use HTTPS" severity: "major" category: "transport" standard: "OWASP" check_type: "form_check" details: description: "Form submissions should always go to HTTPS endpoints" - id: "sec-target-blank-rel" name: "Target Blank Security" description: "Links with target=_blank should have rel=noopener" severity: "minor" category: "injection" standard: "Web Security Best Practice" check_type: "link_check" details: description: "Prevents tab-napping attacks via window.opener" recommended: 'rel="noopener noreferrer"' note: "Modern browsers set noopener by default, but explicit is safer" - id: "sec-no-inline-event-handlers" name: "No Inline Event Handlers" description: "Avoid inline event handlers (onclick, onload, etc.)" severity: "minor" category: "injection" standard: "OWASP / CSP" check_type: "attribute_check" details: description: "Inline event handlers are incompatible with strict CSP" blocked_attributes: - "onclick" - "onload" - "onerror" - "onmouseover" - "onsubmit" - "onfocus" - "onblur" - "onchange" - "onkeydown" - "onkeyup" - "onkeypress"