403Webshell
Server IP : 172.67.159.97  /  Your IP : 216.73.217.154
Web Server : nginx/1.24.0
System : Linux wordpress-sites 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64
User : www-data ( 33)
PHP Version : 8.1.34
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/rebeccaone.com/wp-content/plugins/weforms/trunk/security-tests/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/rebeccaone.com/wp-content/plugins/weforms/trunk/security-tests/automated-test.php
<?php
/**
 * Automated Security Test for weForms Plugin
 *
 * This script tests the actual plugin code for unsafe deserialization
 * vulnerabilities.
 *
 * Usage: php automated-test.php /path/to/weforms/plugin
 *
 * @package WeForms Security Tests
 */

// Color output for terminal
class TestColors {
    const RED = "\033[31m";
    const GREEN = "\033[32m";
    const YELLOW = "\033[33m";
    const BLUE = "\033[34m";
    const RESET = "\033[0m";
    const BOLD = "\033[1m";
}

class WeFormsSecurityTester {
    private $plugin_path;
    private $test_results = [];
    private $vulnerable_files = [];
    private $patched_files = [];

    public function __construct($plugin_path) {
        $this->plugin_path = rtrim($plugin_path, '/');

        if (!is_dir($this->plugin_path)) {
            die("Error: Plugin path does not exist: {$this->plugin_path}\n");
        }
    }

    /**
     * Run all security tests
     */
    public function run_tests() {
        $this->print_header("WEFORMS SECURITY VULNERABILITY TEST SUITE");

        echo "Plugin Path: {$this->plugin_path}\n\n";

        // Test 1: Scan for unsafe unserialize calls
        $this->test_scan_unsafe_unserialize();

        // Test 2: Verify safe deserialization patterns
        $this->test_verify_safe_patterns();

        // Test 3: Check for remaining maybe_unserialize
        $this->test_check_maybe_unserialize();

        // Test 4: Verify allowed_classes parameter
        $this->test_verify_allowed_classes();

        // Print summary
        $this->print_summary();
    }

    /**
     * Test 1: Scan for unsafe unserialize calls
     */
    private function test_scan_unsafe_unserialize() {
        $this->print_test_header("TEST 1: Scanning for Unsafe unserialize() Calls");

        $files_to_check = [
            'includes/admin/class-privacy.php',
            'includes/api/class-weforms-forms-controller.php',
            'includes/class-ajax.php',
            'includes/class-form-entry.php',
            'includes/class-form.php',
            'includes/functions.php',
        ];

        $found_unsafe = false;

        foreach ($files_to_check as $file) {
            $full_path = $this->plugin_path . '/' . $file;

            if (!file_exists($full_path)) {
                echo "  ⚠️  File not found: {$file}\n";
                continue;
            }

            $content = file_get_contents($full_path);

            // Look for unsafe unserialize patterns
            // Pattern: unserialize( without ['allowed_classes' => false]
            preg_match_all('/unserialize\s*\(\s*[^)]+\)\s*;/', $content, $all_matches, PREG_SET_ORDER);

            $unsafe_matches = [];
            foreach ($all_matches as $match) {
                // Check if it has allowed_classes parameter nearby
                $context_start = max(0, strpos($content, $match[0]) - 200);
                $context = substr($content, $context_start, 300);
                if (!preg_match('/allowed_classes.*false/', $context)) {
                    $unsafe_matches[] = $match;
                }
            }

            if (!empty($unsafe_matches)) {
                echo TestColors::RED . "  ❌ VULNERABLE: {$file}" . TestColors::RESET . "\n";
                foreach ($unsafe_matches as $match) {
                    echo "     Found: " . trim($match[0]) . "\n";
                }
                $this->vulnerable_files[] = $file;
                $found_unsafe = true;
            }
        }

        if (!$found_unsafe) {
            echo TestColors::GREEN . "  ✅ PASS: No unsafe unserialize() calls found\n" . TestColors::RESET;
            $this->test_results['unsafe_unserialize'] = 'PASS';
        } else {
            echo TestColors::RED . "  ❌ FAIL: Found unsafe unserialize() calls\n" . TestColors::RESET;
            $this->test_results['unsafe_unserialize'] = 'FAIL';
        }

        echo "\n";
    }

    /**
     * Test 2: Verify safe deserialization patterns
     */
    private function test_verify_safe_patterns() {
        $this->print_test_header("TEST 2: Verifying Safe Deserialization Patterns");

        $files_to_check = [
            'includes/admin/class-privacy.php' => 1,
            'includes/api/class-weforms-forms-controller.php' => 1,
            'includes/class-ajax.php' => 1,
            'includes/class-form-entry.php' => 5,
            'includes/class-form.php' => 1,
        ];

        $all_verified = true;

        foreach ($files_to_check as $file => $expected_count) {
            $full_path = $this->plugin_path . '/' . $file;

            if (!file_exists($full_path)) {
                continue;
            }

            $content = file_get_contents($full_path);

            // Count safe patterns: allowed_classes => false
            $safe_count = preg_match_all(
                '/unserialize\s*\([^)]+\[\s*[\'"]allowed_classes[\'"]\s*=>\s*false\s*\]/',
                $content
            );

            if ($safe_count >= $expected_count) {
                echo TestColors::GREEN . "  ✅ {$file}: {$safe_count}/{$expected_count} safe patterns" . TestColors::RESET . "\n";
                $this->patched_files[] = $file;
            } else {
                echo TestColors::RED . "  ❌ {$file}: {$safe_count}/{$expected_count} safe patterns (MISSING: " . ($expected_count - $safe_count) . ")" . TestColors::RESET . "\n";
                $all_verified = false;
            }
        }

        if ($all_verified) {
            echo TestColors::GREEN . "\n  ✅ PASS: All expected safe patterns verified\n" . TestColors::RESET;
            $this->test_results['safe_patterns'] = 'PASS';
        } else {
            echo TestColors::RED . "\n  ❌ FAIL: Some safe patterns missing\n" . TestColors::RESET;
            $this->test_results['safe_patterns'] = 'FAIL';
        }

        echo "\n";
    }

    /**
     * Test 3: Check for remaining maybe_unserialize
     */
    private function test_check_maybe_unserialize() {
        $this->print_test_header("TEST 3: Checking for Unsafe maybe_unserialize() Calls");

        $files_to_check = [
            'includes/class-form-entry.php',
            'includes/class-form.php',
        ];

        $found_unsafe = false;

        foreach ($files_to_check as $file) {
            $full_path = $this->plugin_path . '/' . $file;

            if (!file_exists($full_path)) {
                continue;
            }

            $content = file_get_contents($full_path);

            // Look for maybe_unserialize
            if (preg_match('/maybe_unserialize\s*\(/', $content, $matches)) {
                echo TestColors::RED . "  ⚠️  FOUND: {$file} still uses maybe_unserialize()\n" . TestColors::RESET;
                $found_unsafe = true;
            }
        }

        if (!$found_unsafe) {
            echo TestColors::GREEN . "  ✅ PASS: No maybe_unserialize() calls found\n" . TestColors::RESET;
            $this->test_results['maybe_unserialize'] = 'PASS';
        } else {
            echo TestColors::YELLOW . "  ⚠️  WARNING: Found maybe_unserialize() calls (should be replaced)\n" . TestColors::RESET;
            $this->test_results['maybe_unserialize'] = 'WARNING';
        }

        echo "\n";
    }

    /**
     * Test 4: Verify allowed_classes parameter
     */
    private function test_verify_allowed_classes() {
        $this->print_test_header("TEST 4: Verifying allowed_classes => false Parameter");

        // Recursively find all PHP files in includes directory
        $all_files = $this->get_php_files_recursive($this->plugin_path . '/includes');
        $all_secure = true;
        $unserialize_count = 0;

        foreach ($all_files as $file) {
            $content = file_get_contents($file);

            // Find all unserialize calls
            preg_match_all('/unserialize\s*\([^;]+;/s', $content, $matches);

            foreach ($matches[0] as $match) {
                $unserialize_count++;

                // Check if it has allowed_classes
                if (!preg_match('/\[\s*[\'"]allowed_classes[\'"]\s*=>\s*false\s*\]/', $match)) {
                    // Skip if it's in a comment
                    if (strpos($match, '//') !== false || strpos($match, '/*') !== false) {
                        continue;
                    }

                    echo TestColors::RED . "  ❌ Missing allowed_classes: " . basename($file) . TestColors::RESET . "\n";
                    echo "     " . trim(substr($match, 0, 80)) . "...\n";
                    $all_secure = false;
                }
            }
        }

        if ($all_secure && $unserialize_count > 0) {
            echo TestColors::GREEN . "  ✅ PASS: All {$unserialize_count} unserialize() calls have allowed_classes => false\n" . TestColors::RESET;
            $this->test_results['allowed_classes'] = 'PASS';
        } elseif ($unserialize_count == 0) {
            echo TestColors::YELLOW . "  ⚠️  WARNING: No unserialize() calls found\n" . TestColors::RESET;
            $this->test_results['allowed_classes'] = 'WARNING';
        } else {
            echo TestColors::RED . "  ❌ FAIL: Some unserialize() calls missing allowed_classes\n" . TestColors::RESET;
            $this->test_results['allowed_classes'] = 'FAIL';
        }

        echo "\n";
    }

    /**
     * Recursively get all PHP files in a directory
     *
     * @param string $directory Directory path to scan
     * @return array Array of PHP file paths
     */
    private function get_php_files_recursive($directory) {
        $php_files = [];

        if (!is_dir($directory)) {
            return $php_files;
        }

        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::SELF_FIRST
        );

        foreach ($iterator as $file) {
            if ($file->isFile() && $file->getExtension() === 'php') {
                $php_files[] = $file->getPathname();
            }
        }

        return $php_files;
    }

    /**
     * Print test summary
     */
    private function print_summary() {
        $this->print_header("TEST SUMMARY");

        $total_tests = count($this->test_results);
        $passed = 0;
        $failed = 0;
        $warnings = 0;

        foreach ($this->test_results as $test => $result) {
            $label = str_pad(ucwords(str_replace('_', ' ', $test)), 30);

            if ($result === 'PASS') {
                echo TestColors::GREEN . "  ✅ {$label}: PASS" . TestColors::RESET . "\n";
                $passed++;
            } elseif ($result === 'FAIL') {
                echo TestColors::RED . "  ❌ {$label}: FAIL" . TestColors::RESET . "\n";
                $failed++;
            } else {
                echo TestColors::YELLOW . "  ⚠️  {$label}: {$result}" . TestColors::RESET . "\n";
                $warnings++;
            }
        }

        echo "\n";
        echo str_repeat("=", 70) . "\n";
        echo "Total Tests: {$total_tests}\n";
        echo TestColors::GREEN . "Passed: {$passed}" . TestColors::RESET . "\n";
        echo TestColors::RED . "Failed: {$failed}" . TestColors::RESET . "\n";
        echo TestColors::YELLOW . "Warnings: {$warnings}" . TestColors::RESET . "\n";
        echo str_repeat("=", 70) . "\n\n";

        // Final verdict
        if ($failed > 0) {
            echo TestColors::RED . TestColors::BOLD . "❌ VERDICT: VULNERABLE - Patch incomplete or not applied" . TestColors::RESET . "\n\n";
            exit(1);
        } elseif ($warnings > 0) {
            echo TestColors::YELLOW . TestColors::BOLD . "⚠️  VERDICT: PARTIALLY SECURE - Some improvements needed" . TestColors::RESET . "\n\n";
            exit(0);
        } else {
            echo TestColors::GREEN . TestColors::BOLD . "✅ VERDICT: SECURE - All tests passed!" . TestColors::RESET . "\n\n";
            exit(0);
        }
    }

    private function print_header($text) {
        echo "\n" . str_repeat("=", 70) . "\n";
        echo TestColors::BOLD . "  " . $text . TestColors::RESET . "\n";
        echo str_repeat("=", 70) . "\n\n";
    }

    private function print_test_header($text) {
        echo str_repeat("-", 70) . "\n";
        echo TestColors::BOLD . $text . TestColors::RESET . "\n";
        echo str_repeat("-", 70) . "\n";
    }
}

// Main execution
if (php_sapi_name() === 'cli') {
    if ($argc < 2) {
        echo "Usage: php automated-test.php /path/to/weforms/plugin\n";
        echo "Example: php automated-test.php /home/user/wp-content/plugins/weforms\n";
        exit(1);
    }

    $plugin_path = $argv[1];
    $tester = new WeFormsSecurityTester($plugin_path);
    $tester->run_tests();
} else {
    die("This script must be run from the command line.\n");
}

Youez - 2016 - github.com/yon3zu
LinuXploit