From 1440ece58516169c82f28de3fda8e20611c5a877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Umut=20I=C5=9F=C4=B1k?= Date: Fri, 18 Jan 2019 23:22:46 +0300 Subject: [PATCH] Finish the initial checks --- composer.json | 3 +- src/Manager.php | 106 +++++++++++++++++++++++++++++++------ src/Settings.php | 9 ++++ wp-vulnerability-check | 0 wp-vulnerability-check.php | 12 ++--- 5 files changed, 106 insertions(+), 24 deletions(-) mode change 100644 => 100755 wp-vulnerability-check diff --git a/composer.json b/composer.json index 8ad6791..646982f 100644 --- a/composer.json +++ b/composer.json @@ -17,8 +17,7 @@ "ext-json": "*" }, "require-dev": { - "phpunit/phpunit": "~4.5", - "jakub-onderka/php-parallel-lint": "~1.0" + "phpunit/phpunit": "~4.5" }, "bin": ["wp-vulnerability-check"] } diff --git a/src/Manager.php b/src/Manager.php index 15b2173..42f67b1 100644 --- a/src/Manager.php +++ b/src/Manager.php @@ -11,7 +11,23 @@ class Manager */ public function check(Settings $settings) { - $plugins = $this->getFilesFromPaths($settings->path, $settings->excluded); + $files = scandir($settings->path); + $plugins = array(); + foreach ($files as $key => $value) { + if ($value === '.' || $value === '..') { + continue; + } + + if (is_dir($settings->path . DIRECTORY_SEPARATOR . $value)) { + if (file_exists($settings->path . DIRECTORY_SEPARATOR . $value . DIRECTORY_SEPARATOR . $value . ".php")) { + $plugins[$value] = $value . DIRECTORY_SEPARATOR . $value . ".php"; + } + + continue; + } + + $plugins[$value] = $value; + } /** @var Result[] $results */ $results = array(); @@ -19,16 +35,25 @@ public function check(Settings $settings) $checkedPlugins = 0; $vulnerablePlugins = 0; $results = array(); + $totalPluginCount = count($plugins); - foreach ($plugins as $plugin) { + foreach ($plugins as $plugin => $file) { try { - $fileResult = $this->checkPlugin($plugin); - $checkedPlugins++; + $vulResult = $this->checkPlugin($plugin, $file, $settings); + + if (!isset($vulResult[$plugin])) { + continue; + } + $checkedPlugins++; // Get Vulnerabilities and check the plugin with version - $vulnerablePlugins++; - echo "v"; // For vulnerability - echo "."; // For success + if (count($vulResult[$plugin]['vulnerabilities'])) { + $vulnerablePlugins++; + echo "v"; // For vulnerability + } else { + echo "."; // For success + } + $pluginResult = array('Vulnerability Result'); $results = array_merge($results, $pluginResult); } catch (Exception\Exception $e) { @@ -47,18 +72,20 @@ public function check(Settings $settings) $message .= "no vulnerability found."; } else { $message .= "some vulnerability(s) in $vulnerablePlugins "; - $message .= ($vulnerablePlugins === 1 ? 'file' : 'files'); + $message .= ($vulnerablePlugins === 1 ? 'plugin.' : 'plugins.'); } echo $message . PHP_EOL; if (!empty($results)) { - $output->writeNewLine(); - - foreach ($results as $result) { + if ($settings->output != 'NO') { + echo PHP_EOL; echo str_repeat('-', 60); - echo $result[0]; echo PHP_EOL; + foreach ($results as $result) { + echo $result; + echo PHP_EOL; + } } return false; @@ -71,19 +98,66 @@ public function check(Settings $settings) * Check plugin with plugin name via API * * @param string $pluginName + * @param string $pluginFile * @param Settings $settings * @return Result[] * @throws Exception */ - public function checkPlugin($pluginName, Settings $settings = null) + public function checkPlugin($pluginName, $pluginFile, Settings $settings = null) { if ($settings === null) { $settings = new Settings(); } - $results = array(); + $meta = $this->getPluginMetaData( + $settings->path . DIRECTORY_SEPARATOR . $pluginFile + ); + + $vulnerabilities = $this->get($pluginName, "c0DR3SJklWNn26oP6lZ7ybrHCrR4UaSqD0dhKcC2m0U"); + return $vulnerabilities; + } - return $results; + /** + * Get plugin meta data from the header comment block + * + * @param string $file File path of the plugin file + * @return array The array of the meta values + */ + private function getPluginMetaData($file) + { + $all_headers = array( + 'Name' => 'Plugin Name', + 'PluginURI' => 'Plugin URI', + 'Version' => 'Version', + 'Description' => 'Description', + 'Author' => 'Author', + 'AuthorURI' => 'Author URI', + 'TextDomain' => 'Text Domain', + 'DomainPath' => 'Domain Path', + 'Network' => 'Network', + // Site Wide Only is deprecated in favor of Network. + '_sitewide' => 'Site Wide Only' + ); + // We don't need to write to the file, so just open for reading. + $fp = fopen($file, 'r'); + + // Pull only the first 8kiB of the file in. + $file_data = fread($fp, 8192); + + // PHP will close file handle, but we are good citizens. + fclose($fp); + + // Make sure we catch CR-only line endings. + $file_data = str_replace("\r", "\n", $file_data); + + foreach ($all_headers as $field => $regex) { + if (preg_match( '/^[ \t\/*#@]*' . preg_quote($regex, '/') . ':(.*)$/mi', $file_data, $match) && $match[1]) + $all_headers[$field] = trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $match[1])); + else + $all_headers[$field] = ''; + } + + return $all_headers; } /** @@ -110,6 +184,6 @@ private function get($pluginName, $APIToken) { curl_close ($ch); - return json_decode($server_output); + return json_decode($server_output, true); } } diff --git a/src/Settings.php b/src/Settings.php index 09f03f1..0a0d862 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -21,6 +21,12 @@ class Settings */ public $colors = true; + /** + * Format of console output + * @var string + */ + public $output = 'NO'; + /** * The API Token taken from the wpvulndb.com site to use API. * @var bool @@ -50,6 +56,9 @@ public static function parseArguments(array $arguments) case '--exclude': $setting->excluded[] = explode(',', $arguments->getNext()); break; + case '--output': + $setting->output = trim($arguments->getNext()); + break; case '--no-colors': $setting->colors = false; break; diff --git a/wp-vulnerability-check b/wp-vulnerability-check old mode 100644 new mode 100755 diff --git a/wp-vulnerability-check.php b/wp-vulnerability-check.php index 3a580a5..b418e48 100644 --- a/wp-vulnerability-check.php +++ b/wp-vulnerability-check.php @@ -18,18 +18,18 @@ function showOptions() { --path Full path for the plugin directory of your WordPress installation. --token Token got from wpvulndb.com --exclude Exclude the plugins given in comma separated format. + --output The format of output. Valid values JSON, READABLE, NO (Default). --version Show version. --help Print this help. -WP Vulnerability Check version ---------------------------- -Usage: - wp-vulnerability-check [options] -