/** * HVAC Community Events - Build System Security Tests * * Focused security testing for the critical vulnerabilities identified: * 1. Manifest integrity vulnerability - no validation of manifest.json tampering * 2. User agent security vulnerability - unsanitized user agent parsing * 3. Missing bundle validation - bundles enqueued without existence checks * 4. No graceful degradation - no fallback when bundles fail * * @package HVAC_Community_Events * @since 2.0.0 */ const fs = require('fs').promises; const path = require('path'); const { test, expect } = require('@playwright/test'); const { execSync } = require('child_process'); // Security test configuration const SECURITY_CONFIG = { PROJECT_ROOT: path.resolve(__dirname, '..'), MANIFEST_PATH: path.resolve(__dirname, '../assets/js/dist/manifest.json'), BUNDLED_ASSETS_CLASS: path.resolve(__dirname, '../includes/class-hvac-bundled-assets.php'), BASE_URL: process.env.BASE_URL || 'http://localhost:8080', // Critical security payloads ATTACK_PAYLOADS: { // Manifest integrity attacks MANIFEST_XSS: '{"hvac-core.js": ".js"}', MANIFEST_SCRIPT_INJECTION: '{"hvac-core.js": "javascript:alert(\'MANIFEST_INJECTION\')"}', MANIFEST_PATH_TRAVERSAL: '{"hvac-core.js": "../../../../etc/passwd"}', MANIFEST_DATA_URI: '{"hvac-core.js": "data:text/javascript,alert(\'DATA_URI_ATTACK\')"}', MANIFEST_PROTOCOL_POLLUTION: '{"hvac-core.js": "file:///etc/passwd"}', // User agent injection attacks USER_AGENT_SCRIPT: 'Mozilla/5.0 (X11; Linux x86_64) ', USER_AGENT_SQL: 'Mozilla/5.0\'; DROP TABLE wp_users; --', USER_AGENT_PHP_INJECTION: 'Mozilla/5.0 ', USER_AGENT_COMMAND_INJECTION: 'Mozilla/5.0 $(rm -rf /)', USER_AGENT_NULL_BYTE: 'Mozilla/5.0\x00', // Bundle path attacks BUNDLE_PATH_TRAVERSAL: '../../../wp-config.php', BUNDLE_ABSOLUTE_PATH: '/etc/passwd', BUNDLE_PROTOCOL_ATTACK: 'http://evil.com/malicious.js', BUNDLE_DOUBLE_ENCODING: '%2e%2e%2f%2e%2e%2f%2e%2e%2fwp-config.php' } }; /** * Security Test Framework */ class SecurityTestFramework { /** * Backup original files before security testing */ static async backupOriginalFiles() { const backups = {}; try { // Backup manifest if (await fs.access(SECURITY_CONFIG.MANIFEST_PATH).then(() => true).catch(() => false)) { const manifestContent = await fs.readFile(SECURITY_CONFIG.MANIFEST_PATH, 'utf-8'); backups.manifest = manifestContent; } } catch (error) { console.warn('Could not backup manifest:', error.message); } return backups; } /** * Restore original files after testing */ static async restoreOriginalFiles(backups) { try { if (backups.manifest) { await fs.writeFile(SECURITY_CONFIG.MANIFEST_PATH, backups.manifest); } else { // Remove test manifest if no backup existed await fs.unlink(SECURITY_CONFIG.MANIFEST_PATH).catch(() => {}); } } catch (error) { console.warn('Could not restore files:', error.message); } } /** * Create malicious manifest for testing */ static async createMaliciousManifest(payload) { await fs.writeFile(SECURITY_CONFIG.MANIFEST_PATH, payload); console.log(`šŸ’€ Created malicious manifest: ${payload.substring(0, 100)}...`); } /** * Analyze PHP code for security vulnerabilities */ static async analyzePHPSecurity() { try { const phpCode = await fs.readFile(SECURITY_CONFIG.BUNDLED_ASSETS_CLASS, 'utf-8'); return { // Check for unsanitized user input hasUnsanitizedUserAgent: phpCode.includes('$_SERVER[\'HTTP_USER_AGENT\']') && !phpCode.includes('sanitize_text_field') && !phpCode.includes('esc_attr'), // Check for unvalidated file paths hasUnvalidatedPaths: phpCode.includes('file_get_contents') && !phpCode.includes('wp_safe_remote_get') && !phpCode.includes('validate_file'), // Check for missing nonce verification hasMissingNonce: phpCode.includes('$_POST') && !phpCode.includes('wp_verify_nonce'), // Check for direct file inclusion hasDirectInclusion: phpCode.includes('include') || phpCode.includes('require') || phpCode.includes('file_get_contents'), // Check for output escaping hasMissingEscaping: phpCode.includes('echo ') && !phpCode.includes('esc_html') && !phpCode.includes('esc_attr'), codeLength: phpCode.length }; } catch (error) { console.error('Could not analyze PHP security:', error.message); return { error: error.message }; } } /** * Test for common web vulnerabilities */ static async testWebVulnerabilities(page, testUrl) { const vulnerabilities = { xss: false, sqli: false, pathTraversal: false, codeInjection: false, errorDisclosure: false }; const errors = []; // Monitor console errors that might indicate vulnerabilities page.on('console', (message) => { if (message.type() === 'error') { errors.push(message.text()); // Check for XSS execution if (message.text().includes('XSS') || message.text().includes('alert')) { vulnerabilities.xss = true; } } }); // Monitor network requests for suspicious activity const suspiciousRequests = []; page.on('request', (request) => { const url = request.url(); if (url.includes('../') || url.includes('/etc/') || url.includes('passwd') || url.includes('DROP TABLE') || url.includes('