UNPKG

@casoon/auditmysite

Version:

A comprehensive command-line tool for automated accessibility, security, performance, and SEO testing using Playwright and pa11y, based on sitemap URLs

158 lines 7.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SecurityHeadersTest = void 0; const base_test_1 = require("../base-test"); class SecurityHeadersTest extends base_test_1.BaseAccessibilityTest { constructor() { super(...arguments); this.name = 'Security Headers Test'; this.description = 'Checks for essential security headers to protect against common web vulnerabilities'; this.category = 'security'; this.priority = 'critical'; this.standards = ['OWASP Security Guidelines', 'Security Best Practices']; } async run(context) { const { page, url } = context; try { // Navigate to the page to capture headers await page.goto(url, { waitUntil: 'networkidle' }); // Get response headers const response = await page.waitForResponse(url); const headers = response.headers(); const issues = []; const warnings = []; const details = {}; // Check Content Security Policy (CSP) const csp = headers['content-security-policy'] || headers['x-content-security-policy']; if (!csp) { issues.push('Missing Content Security Policy (CSP) header - critical for XSS protection'); } else { details.csp = csp; if (!csp.includes('default-src')) { warnings.push('CSP missing default-src directive'); } if (!csp.includes('script-src')) { warnings.push('CSP missing script-src directive'); } } // Check HTTP Strict Transport Security (HSTS) const hsts = headers['strict-transport-security']; if (!hsts) { issues.push('Missing HTTP Strict Transport Security (HSTS) header - critical for HTTPS enforcement'); } else { details.hsts = hsts; if (!hsts.includes('max-age=')) { warnings.push('HSTS missing max-age directive'); } if (!hsts.includes('includeSubDomains')) { warnings.push('HSTS should include includeSubDomains directive'); } } // Check X-Frame-Options const xFrameOptions = headers['x-frame-options']; if (!xFrameOptions) { issues.push('Missing X-Frame-Options header - protection against clickjacking'); } else { details.xFrameOptions = xFrameOptions; if (!['DENY', 'SAMEORIGIN'].includes(xFrameOptions.toUpperCase())) { warnings.push('X-Frame-Options should be DENY or SAMEORIGIN'); } } // Check X-Content-Type-Options const xContentTypeOptions = headers['x-content-type-options']; if (!xContentTypeOptions) { warnings.push('Missing X-Content-Type-Options header - prevents MIME type sniffing'); } else { details.xContentTypeOptions = xContentTypeOptions; if (xContentTypeOptions !== 'nosniff') { warnings.push('X-Content-Type-Options should be "nosniff"'); } } // Check X-XSS-Protection const xXSSProtection = headers['x-xss-protection']; if (!xXSSProtection) { warnings.push('Missing X-XSS-Protection header - additional XSS protection'); } else { details.xXSSProtection = xXSSProtection; if (!xXSSProtection.includes('1; mode=block')) { warnings.push('X-XSS-Protection should be "1; mode=block"'); } } // Check Referrer Policy const referrerPolicy = headers['referrer-policy']; if (!referrerPolicy) { warnings.push('Missing Referrer Policy header - controls referrer information'); } else { details.referrerPolicy = referrerPolicy; const validPolicies = ['no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'same-origin', 'strict-origin', 'strict-origin-when-cross-origin', 'unsafe-url']; if (!validPolicies.includes(referrerPolicy)) { warnings.push(`Invalid Referrer Policy: ${referrerPolicy}`); } } // Check Permissions Policy (formerly Feature Policy) const permissionsPolicy = headers['permissions-policy']; if (!permissionsPolicy) { warnings.push('Missing Permissions Policy header - controls browser features'); } else { details.permissionsPolicy = permissionsPolicy; } // Check Cross-Origin Resource Policy const corp = headers['cross-origin-resource-policy']; if (!corp) { warnings.push('Missing Cross-Origin Resource Policy header - prevents cross-origin resource access'); } else { details.corp = corp; if (!['same-site', 'same-origin', 'cross-origin'].includes(corp)) { warnings.push(`Invalid Cross-Origin Resource Policy: ${corp}`); } } // Check Cross-Origin Embedder Policy const coep = headers['cross-origin-embedder-policy']; if (!coep) { warnings.push('Missing Cross-Origin Embedder Policy header - enables cross-origin isolation'); } else { details.coep = coep; if (!['require-corp', 'credentialless'].includes(coep)) { warnings.push(`Invalid Cross-Origin Embedder Policy: ${coep}`); } } // Check Cross-Origin Opener Policy const coop = headers['cross-origin-opener-policy']; if (!coop) { warnings.push('Missing Cross-Origin Opener Policy header - prevents cross-origin window access'); } else { details.coop = coop; if (!['same-origin', 'same-origin-allow-popups', 'unsafe-none'].includes(coop)) { warnings.push(`Invalid Cross-Origin Opener Policy: ${coop}`); } } // Check for HTTPS if (!url.startsWith('https://')) { issues.push('Site is not using HTTPS - critical security requirement'); } // Calculate security score const totalChecks = 10; const passedChecks = totalChecks - issues.length - warnings.length; const securityScore = Math.round((passedChecks / totalChecks) * 100); details.securityScore = securityScore; details.totalChecks = totalChecks; details.passedChecks = passedChecks; return this.createResult(issues.length === 0, issues.length + warnings.length, issues, warnings, details); } catch (error) { return this.createErrorResult(`Security Headers Test failed: ${error}`); } } } exports.SecurityHeadersTest = SecurityHeadersTest; //# sourceMappingURL=security-headers-test.js.map