test_authentication_hardening(); $this->test_sql_injection_prevention(); $this->test_xss_protection(); $this->test_rate_limiting(); $this->test_csrf_protection(); $this->print_summary(); } /** * Test 1: Authentication Hardening */ public function test_authentication_hardening() { echo "1️⃣ TESTING: Authentication Hardening\n"; echo str_repeat("-", 40) . "\n"; // Test endpoints that should be protected $protected_endpoints = [ '/status', '/health', '/version', '/auth/login', '/auth/forgot-password', '/auth/reset-password' ]; foreach ($protected_endpoints as $endpoint) { $result = $this->test_endpoint_security($endpoint); if ($result['uses_return_true']) { $this->test_results[] = [ 'test' => 'AUTH_HARDENING', 'endpoint' => $endpoint, 'status' => '❌ FAIL', 'details' => 'Still uses __return_true vulnerability' ]; echo " ❌ {$endpoint}: Still vulnerable (__return_true)\n"; } else { $this->test_results[] = [ 'test' => 'AUTH_HARDENING', 'endpoint' => $endpoint, 'status' => '✅ PASS', 'details' => 'Uses Security_Manager authentication' ]; echo " ✅ {$endpoint}: Protected with Security_Manager\n"; } } echo "\n"; } /** * Test 2: SQL Injection Prevention */ public function test_sql_injection_prevention() { echo "2️⃣ TESTING: SQL Injection Prevention\n"; echo str_repeat("-", 40) . "\n"; // Check daily_maintenance method $api_init_file = __DIR__ . '/src/includes/class-api-init.php'; if (!file_exists($api_init_file)) { echo " ⚠️ API Init file not found\n\n"; return; } $content = file_get_contents($api_init_file); // Check for prepared statements if (strpos($content, '$wpdb->prepare(') !== false) { echo " ✅ Uses prepared statements\n"; // Check for vulnerable direct queries if (strpos($content, 'WHERE expires_at < NOW()') === false) { echo " ✅ SQL injection vulnerability fixed\n"; $this->test_results[] = [ 'test' => 'SQL_INJECTION', 'status' => '✅ PASS', 'details' => 'Uses prepared statements with proper parameterization' ]; } else { echo " ⚠️ May still have direct SQL queries\n"; $this->test_results[] = [ 'test' => 'SQL_INJECTION', 'status' => '⚠️ PARTIAL', 'details' => 'Uses prepared statements but may have remaining issues' ]; } } else { echo " ❌ No prepared statements found\n"; $this->test_results[] = [ 'test' => 'SQL_INJECTION', 'status' => '❌ FAIL', 'details' => 'Not using prepared statements' ]; } echo "\n"; } /** * Test 3: XSS Protection */ public function test_xss_protection() { echo "3️⃣ TESTING: XSS Protection\n"; echo str_repeat("-", 40) . "\n"; // Check if Security_Manager sanitize_output method exists $security_file = __DIR__ . '/src/includes/class-security-manager.php'; if (file_exists($security_file)) { $content = file_get_contents($security_file); if (strpos($content, 'sanitize_output') !== false) { echo " ✅ Security_Manager has sanitize_output method\n"; if (strpos($content, 'wp_kses') !== false && strpos($content, 'esc_html') !== false) { echo " ✅ Uses WordPress sanitization functions\n"; $this->test_results[] = [ 'test' => 'XSS_PROTECTION', 'status' => '✅ PASS', 'details' => 'Security Manager implements output sanitization' ]; } else { echo " ⚠️ Limited sanitization functions\n"; $this->test_results[] = [ 'test' => 'XSS_PROTECTION', 'status' => '⚠️ PARTIAL', 'details' => 'Basic sanitization but may need enhancement' ]; } } else { echo " ❌ No output sanitization found\n"; $this->test_results[] = [ 'test' => 'XSS_PROTECTION', 'status' => '❌ FAIL', 'details' => 'Missing output sanitization methods' ]; } } else { echo " ❌ Security Manager file not found\n"; $this->test_results[] = [ 'test' => 'XSS_PROTECTION', 'status' => '❌ FAIL', 'details' => 'Security Manager class missing' ]; } echo "\n"; } /** * Test 4: Rate Limiting */ public function test_rate_limiting() { echo "4️⃣ TESTING: Rate Limiting\n"; echo str_repeat("-", 40) . "\n"; $security_file = __DIR__ . '/src/includes/class-security-manager.php'; if (file_exists($security_file)) { $content = file_get_contents($security_file); if (strpos($content, 'check_rate_limit') !== false) { echo " ✅ Rate limiting implemented\n"; if (strpos($content, 'get_transient') !== false) { echo " ✅ Uses WordPress transients for rate limiting\n"; $this->test_results[] = [ 'test' => 'RATE_LIMITING', 'status' => '✅ PASS', 'details' => 'Implements rate limiting with transients' ]; } else { echo " ⚠️ Rate limiting method exists but storage unclear\n"; $this->test_results[] = [ 'test' => 'RATE_LIMITING', 'status' => '⚠️ PARTIAL', 'details' => 'Rate limiting exists but needs verification' ]; } } else { echo " ❌ No rate limiting found\n"; $this->test_results[] = [ 'test' => 'RATE_LIMITING', 'status' => '❌ FAIL', 'details' => 'Rate limiting not implemented' ]; } } else { echo " ❌ Security Manager not found\n"; } echo "\n"; } /** * Test 5: CSRF Protection */ public function test_csrf_protection() { echo "5️⃣ TESTING: CSRF Protection\n"; echo str_repeat("-", 40) . "\n"; $security_file = __DIR__ . '/src/includes/class-security-manager.php'; if (file_exists($security_file)) { $content = file_get_contents($security_file); if (strpos($content, 'validate_csrf_token') !== false || strpos($content, 'wp_verify_nonce') !== false) { echo " ✅ CSRF protection implemented\n"; $this->test_results[] = [ 'test' => 'CSRF_PROTECTION', 'status' => '✅ PASS', 'details' => 'Uses WordPress nonce verification' ]; } else { echo " ❌ No CSRF protection found\n"; $this->test_results[] = [ 'test' => 'CSRF_PROTECTION', 'status' => '❌ FAIL', 'details' => 'CSRF protection not implemented' ]; } } else { echo " ❌ Security Manager not found\n"; } echo "\n"; } /** * Test specific endpoint security */ private function test_endpoint_security($endpoint) { $api_files = [ __DIR__ . '/src/includes/class-api-init.php', __DIR__ . '/src/includes/endpoints/class-auth-endpoints.php' ]; foreach ($api_files as $file) { if (file_exists($file)) { $content = file_get_contents($file); // Look for endpoint registration if (strpos($content, $endpoint) !== false) { // Check if it uses __return_true $endpoint_section = $this->extract_endpoint_section($content, $endpoint); return [ 'uses_return_true' => strpos($endpoint_section, '__return_true') !== false, 'uses_security_manager' => strpos($endpoint_section, 'Security_Manager') !== false ]; } } } return ['uses_return_true' => false, 'uses_security_manager' => false]; } /** * Extract endpoint configuration section */ private function extract_endpoint_section($content, $endpoint) { $endpoint_pos = strpos($content, $endpoint); if ($endpoint_pos === false) { return ''; } // Extract ~200 characters around the endpoint $start = max(0, $endpoint_pos - 100); $length = min(400, strlen($content) - $start); return substr($content, $start, $length); } /** * Print test summary */ public function print_summary() { echo "📊 SECURITY TEST SUMMARY\n"; echo str_repeat("=", 50) . "\n"; $passed = 0; $failed = 0; $partial = 0; foreach ($this->test_results as $result) { if (strpos($result['status'], '✅') !== false) { $passed++; } elseif (strpos($result['status'], '❌') !== false) { $failed++; } else { $partial++; } echo "{$result['status']} {$result['test']}\n"; if (isset($result['endpoint'])) { echo " Endpoint: {$result['endpoint']}\n"; } echo " Details: {$result['details']}\n\n"; } echo "RESULTS:\n"; echo "✅ Passed: {$passed}\n"; echo "⚠️ Partial: {$partial}\n"; echo "❌ Failed: {$failed}\n\n"; $total_tests = count($this->test_results); $score = round(($passed + ($partial * 0.5)) / $total_tests * 100, 1); echo "🏆 SECURITY SCORE: {$score}/100\n"; if ($score >= 90) { echo "🟢 EXCELLENT - Production ready\n"; } elseif ($score >= 75) { echo "🟡 GOOD - Minor issues remain\n"; } elseif ($score >= 50) { echo "🟠 FAIR - Major improvements needed\n"; } else { echo "🔴 CRITICAL - Not suitable for production\n"; } } } // Run security tests if executed directly if (basename(__FILE__) == basename($_SERVER['SCRIPT_NAME'])) { $security_tests = new Security_Test_Suite(); $security_tests->run_all_tests(); }