From 7c964d068dbb91cc1a4cb2a26b21e7e4e80a2922 Mon Sep 17 00:00:00 2001 From: Kyle Taylor Date: Thu, 29 Apr 2021 00:32:15 -0500 Subject: [PATCH 1/6] Ignore IDE config --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index aa4afb3..33b5f38 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ composer.lock *.phar vendor/* behat/* +/.idea From 60a84efc5aedb19a04253839201552ec15c417ec Mon Sep 17 00:00:00 2001 From: Kyle Taylor Date: Thu, 29 Apr 2021 01:38:59 -0500 Subject: [PATCH 2/6] Add initial theme check --- php/commands/launchcheck.php | 63 +++++++--- php/pantheon/checks/themes.php | 211 +++++++++++++++++++++++++++++++++ 2 files changed, 256 insertions(+), 18 deletions(-) create mode 100644 php/pantheon/checks/themes.php diff --git a/php/commands/launchcheck.php b/php/commands/launchcheck.php index 29cb3c9..577d874 100644 --- a/php/commands/launchcheck.php +++ b/php/commands/launchcheck.php @@ -21,7 +21,7 @@ public function all($args, $assoc_args) { $config_check = new \Pantheon\Checks\Config(); $checker->register( $config_check ); $checker->execute(); - + if ( ! $config_check->valid_db ) { WP_CLI::warning( 'Detected invalid database credentials, skipping remaining checks' ); $format = isset($assoc_args['format']) ? $assoc_args['format'] : 'raw'; @@ -39,6 +39,7 @@ public function all($args, $assoc_args) { $searcher->register( new \Pantheon\Checks\Exploited() ); $searcher->execute(); $checker->register( new \Pantheon\Checks\Plugins(isset($assoc_args['all'])) ); + $checker->register( new \Pantheon\Checks\Themes(isset($assoc_args['all'])) ); $checker->register( new \Pantheon\Checks\Cron() ); $checker->register( new \Pantheon\Checks\Objectcache() ); $checker->register( new \Pantheon\Checks\Database() ); @@ -49,10 +50,10 @@ public function all($args, $assoc_args) { /** * Checks for a properly-configured wp-config - * + * * ## OPTIONS - * - * [--format=] + * + * [--format=] * : use to output json * * @when before_wp_load @@ -67,12 +68,12 @@ function config($args, $assoc_args) { /** * Checks the cron - * + * * ## OPTIONS - * - * [--format=] + * + * [--format=] * : use to output json - * + * */ function cron($args, $assoc_args) { $checker = new \Pantheon\Checker(); @@ -81,15 +82,15 @@ function cron($args, $assoc_args) { $format = isset($assoc_args['format']) ? $assoc_args['format'] : 'raw'; \Pantheon\Messenger::emit($format); } - + /** * Check database for potential issues - * + * * ## OPTIONS - * - * [--format=] + * + * [--format=] * : use to output json - * + * */ function database($args, $assoc_args) { $checker = new \Pantheon\Checker(); @@ -101,12 +102,12 @@ function database($args, $assoc_args) { /** * Checks for best practice - * + * * ## OPTIONS - * - * [--format=] + * + * [--format=] * : use to output json - * + * */ function general($args, $assoc_args) { $checker = new \Pantheon\Checker(); @@ -166,7 +167,7 @@ public function secure($args, $assoc_args) { } /** - * checks plugins for vulnerbities using the wpscan vulnerability DB + * checks plugins for vulnerabilities using the wpscan vulnerability DB * - https://wpvulndb.com/api * * ## OPTIONS @@ -191,6 +192,32 @@ public function plugins($args, $assoc_args) { \Pantheon\Messenger::emit($format); } + /** + * checks themes for vulnerabilities using the wpscan vulnerability DB + * - https://wpvulndb.com/api + * + * ## OPTIONS + * + * [--all] + * : check both active and inactive themes ( default is active only ) + * + * [--format=] + * : output as json + * + * ## EXAMPLES + * + * wp launchcheck themes --all + * + */ + public function themes($args, $assoc_args) { + $checker = new \Pantheon\Checker(); + $checker->register( new \Pantheon\Checks\Themes( isset($assoc_args['all'])) ); + $format = isset($assoc_args['format']) ? $assoc_args['format'] : 'raw'; + $checker->execute(); + $format = isset($assoc_args['format']) ? $assoc_args['format'] : 'raw'; + \Pantheon\Messenger::emit($format); + } + /** * checks the files for session_start() * diff --git a/php/pantheon/checks/themes.php b/php/pantheon/checks/themes.php new file mode 100644 index 0000000..2a3445f --- /dev/null +++ b/php/pantheon/checks/themes.php @@ -0,0 +1,211 @@ +check_all_themes = $check_all_themes; + } + + public function init() { + $this->action = 'No action required'; + $this->description = 'Looking for theme info'; + if ( $this->check_all_themes ) { + $this->description .= ' ( active and inactive )'; + } else { + $this->description .= ' ( active only )'; + } + $this->score = 0; + $this->result = ''; + $this->label = 'Themes'; + $this->alerts = array(); + self::$instance = $this; + return $this; + } + + public function run() { + if (!function_exists('wp_get_themes')) { + require_once \WP_CLI::get_config('path') . '/wp-includes/theme.php'; + } + $all_themes = Utils::sanitize_data( wp_get_themes() ); + $update = Utils::sanitize_data( get_theme_updates() ); + $report = array(); + foreach( $all_themes as $theme_path => $data ) { + $slug = $theme_path; + if (stripos($theme_path,'/')) { + $slug = substr($theme_path, 0, stripos($theme_path,'/')); + } + + $vulnerable = $this->is_vulnerable($slug, $data['Version']); + + $needs_update = 0; + $available = '-'; + if (isset($update[$theme_path])) { + $needs_update = 1; + $available = $update[$theme_path]->update->new_version; + } + if ( false === $vulnerable ) { + $vulnerable = "None"; + } else { + $vulnerable = sprintf('more info', $slug ); + } + + $report[$slug] = array( + 'slug' => $slug, + 'installed' => (string) $data['Version'], + 'available' => (string) $available, + 'needs_update' => (string) $needs_update, + 'vulnerable' => $vulnerable, + ); + } + $this->alerts = $report; + } + + /** + * Checks the theme slug against the vulnerability db + * @param $theme_slug string (required) string representing the theme slug + * + * @return array containing vulnerability info or false + */ + protected function getThemeVulnerability($theme_slug ) + { + // Get the vulnerability API token from the platform + $wpvulndb_api_token = getenv('PANTHEON_WPVULNDB_API_TOKEN'); + + // Throw an exception if there is no token + if( false === $wpvulndb_api_token || empty( $wpvulndb_api_token ) ) { + throw new \Exception('No WP Vulnerability DB API Token. Please ensure the PANTHEON_WPVULNDB_API_TOKEN environment variable is set'); + } + + // Set the request URL to the requested theme + $url = 'https://wpvulndb.com/api/v3/themes/' . $theme_slug; + + // Add the token to the headers + $headers = array( + 'Content-Type: application/json', + 'User-Agent: pantheon/wp_launch_check', + 'Authorization: Token token=' . $wpvulndb_api_token + ); + + // Make the request to the API + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + $result = curl_exec($ch); + curl_close($ch); + + // Return false if no result from the API + if( false === $result ) { + return false; + } + + // Decode the result from the API + $result = json_decode( $result, true ); + + // Return false if the specified theme slug is not in the result + if( ! isset( $result[$theme_slug] ) ) { + return false; + } + + // Return the requested theme vulnerability info + return $result[$theme_slug]; + } + + /** + * Checks a theme by slug and version for vulnerabilities + * @param $theme_slug string (required) string representing the theme slug + * @param $current_version string (required) string representing the theme version + * + * @return array containing the vulnerability or false + */ + public function is_vulnerable($theme_slug, $current_version) { + + // Fetch the theme data if we don't have it already + if( !isset( $theme_data[$theme_slug] ) ){ + $theme_results = $this->getThemeVulnerability( $theme_slug ); + + // Return false if no theme results from the vulnerability API + if( false === $theme_results ){ + return false; + } + } + + // No issues if the theme has no vulnerabilities + if ( ! isset( $theme_results['vulnerabilities'] ) || empty( $theme_results['vulnerabilities'] ) ) { + return false; + } + + + // Loop through all vulnerabilities + foreach ( $theme_results['vulnerabilities'] as $vulnerability ) { + + // If the vulnerability hasn't been fixed, then there's an issue + if ( ! isset( $vulnerability['fixed_in'] ) ) { + return $vulnerability; + } + + // If the vulnerability has been fixed, but not in the current version, there's an issue + if ( version_compare( $vulnerability['fixed_in'], $current_version,'>' ) ){ + return $vulnerability; + } + + } + + // If we get this far the current version has no vulnerabilities + return false; + } + + public function message(Messenger $messenger) { + if (!empty($this->alerts)) { + $headers = array( + 'slug'=>"Theme", + 'installed'=>"Current", + 'available' => "Available", + 'needs_update'=>"Needs Update", + 'vulnerable'=>"Vulnerabilities" + ); + $rows = array(); + $count_update = 0; + $count_vuln = 0; + foreach( $this->alerts as $alert ) { + $class = 'ok'; + if ($alert['needs_update']) { + $class = 'warning'; + $count_update++; + } + if ('None' != $alert['vulnerable']) { + $class = 'error'; + $count_vuln++; + } + $rows[] = array('class'=>$class, 'data' => $alert); + } + + $rendered = PHP_EOL; + $rendered .= sprintf("Found %d themes needing updates and %d known vulnerabilities ... \n".PHP_EOL, $count_update, $count_vuln); + $rendered .= View::make('table', array('headers'=>$headers,'rows'=>$rows)); + + $this->result .= $rendered; + if ($count_update > 0) { + $this->score = 1; + $this->action = "You should update all out-of-date themes"; + } + + if ($count_vuln > 0) { + $this->score = 2; + $this->action = "Update themes to fix vulnerabilities"; + } + } else { + $this->result .= "No themes found."; + } + $messenger->addMessage(get_object_vars($this)); + } +} From 3fa0f2f8eff2725f42ffec659c8508f0b23a73af Mon Sep 17 00:00:00 2001 From: Kyle Taylor Date: Thu, 29 Apr 2021 03:59:27 -0500 Subject: [PATCH 3/6] Fix theme checking and object access, add documentation --- CHECKS.md | 38 +++++++++++++++++++--------------- README.md | 9 ++++---- php/commands/launchcheck.php | 6 ++---- php/pantheon/checks/themes.php | 34 ++++++++++++++++++++---------- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/CHECKS.md b/CHECKS.md index 788b3d2..85a890c 100644 --- a/CHECKS.md +++ b/CHECKS.md @@ -2,25 +2,25 @@ All the checks in this extension should be explained in detail here. This file should be organized by command and type checker -There are currently two broad types of checkers. - * [\Pantheon\Checker](php/pantheon/checker.php): These checks simply examine a piece of data and register and alert if the data exists. For instance, does the ```wp-content/object-cache.php``` exist? If so some object caching is enabled. +There are currently two broad types of checkers. + * [\Pantheon\Checker](php/pantheon/checker.php): These checks simply examine a piece of data and register and alert if the data exists. For instance, does the ```wp-content/object-cache.php``` exist? If so some object caching is enabled. * [\Pantheon\Filesearcher](php/pantheon/filesearcher.php): These checks are functionally the same as the above except that before being run the class uses [\Symfony\Component\Finder\Finder](http://symfony.com/doc/current/components/finder.html) to load a list of files to be checked and then runs the specified check on each file. The logic is slightly different here to allow the Finder operation to *only* run once even when multiple "Filesearcher" children are running -The Checker oject has two key methods +The Checker oject has two key methods * ```register( Check $check )```: receives an instance of a check to run. * ```execute()```: executes all registered checks - -The checks themselves are all extensions of the [\Patheon\Checkimplementation](php/pantheon/Checkimplemtation.php) class, each containing the following methods: + +The checks themselves are all extensions of the [\Patheon\Checkimplementation](php/pantheon/Checkimplemtation.php) class, each containing the following methods: * ```init()``` * ```run()``` * ```message()```; The Checker object holds a collection of Check objects which it iterates and invokes each of these methods. In the case of the Filesearcher object, the ```init()``` method generates the file list ( if not already present ) and the ```run()``` method is passed a $file parameter. -The message method recieves a [\Pantheon\Messsenger](php/pantheon/messenger.php) and updates the various Check object properties for output. The output of each check is simply the formatted representation of the object properties. +The message method receives a [\Pantheon\Messsenger](php/pantheon/messenger.php) and updates the various Check object properties for output. The output of each check is simply the formatted representation of the object properties. -**Check Obect Properties:** +**Check Object Properties:** * ```$name```: machine name of the check for use at the index of the returned JSON ( if json is specified ) * ```$description```: textual description of what the check does * ```$label```: display version of check name used on dashboard @@ -28,7 +28,7 @@ The message method recieves a [\Pantheon\Messsenger](php/pantheon/messenger.php) 0: ok (green) 1: warning (orange) 2: error (red) - * ```$result```: rendered html returned for use on the dashboard ( @TODO this should eventual return raw output as well when dashboard is not the intended client ) + * ```$result```: rendered html returned for use on the dashboard ( @TODO this should eventually return raw output as well when dashboard is not the intended client ) * ```$alerts```: an array of alerts to rendered for the ```$result```. Each alert should be an array: ``` array( 'code' => 2, 'class' => 'error', @@ -47,9 +47,9 @@ This check looks for insecure code by running ````preg_match("#.*(eval|base64_de **Check:** [\Pantheon\Check\Exploited](php/pantheon/checks/exploited.php) This check attempts to find actual exploits by running ```'.*eval\(.*base64_decode\(.*';```. The goal here is to find instance of ```eval``` operating on decoded base64, which is almost certainly a bad idea. This regex should be refined because now it technically could alert when it finds the two functions on the same page but not necessary in the right order, leading to a false positive. -## Regular Checkers +## Regular Checkers -### General +### General **Check:** [\Pantheon\Checks\General](php/pantheon/checks/general.php) This check does the following: * Checks for WP_DEBUG=True, returns 'ok' if in dev, 'warning; in live @@ -57,24 +57,28 @@ This check does the following: * Counts active plugins. Alerts if more than 100 are active * Checks database settings for ```home``` and ```siteurl``` and whether they match. If they do not it recommends fixing. You can do this with WP_CLI/Terminus using 'terminus wp search-replace 'domain1' 'domain2' --site=sitename --env=dev' * Checks whether WP Super Cache and/or W3 Total Cache are found and alerts 'warning' if so. - * + * ### Database -**Database:** [\Pantheon\Checks\Database](php/pantheon/checks/database.php) +**Database:** [\Pantheon\Checks\Database](php/pantheon/checks/database.php) This check runs the following db checks * Runs this query ```SELECT TABLES.TABLE_NAME, TABLES.TABLE_SCHEMA, TABLES.TABLE_ROWS, TABLES.DATA_LENGTH, TABLES.ENGINE from information_schema.TABLES where TABLES.TABLE_SCHEMA = '%s'``` and checks that all tables as set to InnoDb storage engine, alerts 'error' if not and specifies a query that can be run to fix the issue. - * Also checks number of rows in the options table. If over 10,000 it alerts 'error' because this is an indication that expired transients are stacking up or that they are using a lugin that over uses the options table. A bloated options table can be a major cause of WP performance issues. - * Counts options that are set to 'autoload', alerts is more than 1,000 are found. This is relevant because WordPress runs ```SELECT * FROM wp_options WHERE autoload = 'yes'``` on every page load to prepopulate the runtime cache. In cases where the query takes to long or returns too much data this can slow down page load. The only benefit to the runtime cache comes when object caching is not in use, but it is strongly encourage that some kind of object cache is always in use. + * Also checks number of rows in the options table. If over 10,000 it alerts 'error' because this is an indication that expired transients are stacking up or that they are using a lugin that over uses the options table. A bloated options table can be a major cause of WP performance issues. + * Counts options that are set to 'autoload', alerts is more than 1,000 are found. This is relevant because WordPress runs ```SELECT * FROM wp_options WHERE autoload = 'yes'``` on every page load to prepopulate the runtime cache. In cases where the query takes to long or returns too much data this can slow down page load. The only benefit to the runtime cache comes when object caching is not in use, but it is strongly encourage that some kind of object cache is always in use. * Looks for transients and expired transients. Some plugins will use transients regularly but not add a garbage collection cron task. Core WordPress has not garbage collection for the transient api. Over time this can cause transients to bloat the ```wp_options``` database as mentioned above. ### Cron **Cron:** [\Pantheon\Checks\Cron](php/commands/checks/cron.php) -This check simple examines whether ```DISABLE_WP_CRON``` evaluates ```true``` to see if cron has been disabled. ( We should probably also curl the wp-cron.php?doing_wp_cron and ensure we get a 200 ). Some hosts disable the default WP_Cron functionality, substituting a system cron, because the HTTP base WP_Cron can sometimes have race conditions develop causing what might be referred to as "runaway cron", in which HTTP multiple requests trigger the cron a small amount of time causing a spike in PHP/MySQL resource consumption. This check also dumps the scheduled tasks into a table using ```get_option('cron')```. +This check simple examines whether ```DISABLE_WP_CRON``` evaluates ```true``` to see if cron has been disabled. ( We should probably also curl the wp-cron.php?doing_wp_cron and ensure we get a 200 ). Some hosts disable the default WP_Cron functionality, substituting a system cron, because the HTTP base WP_Cron can sometimes have race conditions develop causing what might be referred to as "runaway cron", in which HTTP multiple requests trigger the cron a small amount of time causing a spike in PHP/MySQL resource consumption. This check also dumps the scheduled tasks into a table using ```get_option('cron')```. ### object-cache **objectcache** [\Pantheon\Checks\Cron](php/commands/checks/objectcache.php) -Checks is the ```wp-content/object-cache.php``` exists to detemine whether object caching is in use. Checks that the ```global $redis_server``` variable is not empty to determine whether redis is being used. +Checks is the ```wp-content/object-cache.php``` exists to determine whether object caching is in use. Checks that the ```global $redis_server``` variable is not empty to determine whether redis is being used. -### plugins +### Plugins **plugins** [\Pantheon\Checks\Plugins](php/commands/checks/plugins.php) Checks all plugins against the wpvulndb.com database we license. Alerts 'error' if a vulnerability is found and links to the wpvulndb.com page for more info. Also checks for available updates and alerts 'warning' if plugins needing an update are found. + +### Themes +**themes** [\Pantheon\Checks\Themes](php/commands/checks/themes.php) +Checks all themes against the wpvulndb.com database we license. Alerts 'error' if a vulnerability is found and links to the wpvulndb.com page for more info. Also checks for available updates and alerts 'warning' if themes needing an update are found. diff --git a/README.md b/README.md index 11a58a7..2994f33 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ # WP Launch Check -WP Launch Check is an extension for WP-CLI designed for Pantheon.io WordPress customers. While designed initially for the Pantheon dashboard it is intended to be fully usable outside of Pantheon. +WP Launch Check is an extension for WP-CLI designed for Pantheon.io WordPress customers. While designed initially for the Pantheon dashboard it is intended to be fully usable outside of Pantheon. [![Build Status](https://travis-ci.org/pantheon-systems/wp_launch_check.svg?branch=master)](https://travis-ci.org/pantheon-systems/wp_launch_check) To use WP Launch Check simply run the ```wp launchcheck ``` command like you would any other WP-CLI command. -For more information about WP-CLI you can visit [their github page](https://github.com/wp-cli/wp-cli). +For more information about WP-CLI you can visit [their github page](https://github.com/wp-cli/wp-cli). WP Launch Check should be considered in "BETA". Many of the checks have still not been tested in the wild. If you experience a problem please open an issue. @@ -23,12 +23,13 @@ Once you've done so, you can install this package with `wp package install panth Below is a summary of the available commands. *Full technical description of each check run by each command can be found in the [CHECKS.md](CHECKS.md)* * **wp launchcheck cron** : Checks whether cron is enabled and what jobs are scheduled - * **wp launchcheck general**: General checks for data and best practice, i.e. are you running the debug-bar plugin or have WP_DEBUG defined? This will tell you. + * **wp launchcheck general**: General checks for data and best practice, i.e. are you running the debug-bar plugin or have WP_DEBUG defined? This will tell you. * **wp launchcheck database**: Checks related to the databases. * **wp launchcheck object_cache**: Checks whether object caching is enabled and if on Pantheon whether redis is enabled. - * **wp launchcheck sessions**: Checks for plugins refering to the php session_start() function or the superglobal ```$SESSION``` variable. In either case, if you are on a cloud/distributed platform you will need additional configuration achieve the expected functionality + * **wp launchcheck sessions**: Checks for plugins referring to the php session_start() function or the superglobal ```$SESSION``` variable. In either case, if you are on a cloud/distributed platform you will need additional configuration achieve the expected functionality * **wp launchcheck secure**: Does some rudimentary security checks * **wp launchcheck plugins**: Checks plugins for updates and known vulnerabilities + * **wp launchcheck themes**: Checks themes for updates and known vulnerabilities diff --git a/php/commands/launchcheck.php b/php/commands/launchcheck.php index 577d874..54d6b03 100644 --- a/php/commands/launchcheck.php +++ b/php/commands/launchcheck.php @@ -1,6 +1,6 @@ register( new \Pantheon\Checks\Plugins( isset($assoc_args['all'])) ); - $format = isset($assoc_args['format']) ? $assoc_args['format'] : 'raw'; $checker->execute(); $format = isset($assoc_args['format']) ? $assoc_args['format'] : 'raw'; \Pantheon\Messenger::emit($format); @@ -211,8 +210,7 @@ public function plugins($args, $assoc_args) { */ public function themes($args, $assoc_args) { $checker = new \Pantheon\Checker(); - $checker->register( new \Pantheon\Checks\Themes( isset($assoc_args['all'])) ); - $format = isset($assoc_args['format']) ? $assoc_args['format'] : 'raw'; + $checker->register( new \Pantheon\Checks\Themes( isset($assoc_args['all']) ) ); $checker->execute(); $format = isset($assoc_args['format']) ? $assoc_args['format'] : 'raw'; \Pantheon\Messenger::emit($format); diff --git a/php/pantheon/checks/themes.php b/php/pantheon/checks/themes.php index 2a3445f..fe3bdc0 100644 --- a/php/pantheon/checks/themes.php +++ b/php/pantheon/checks/themes.php @@ -9,6 +9,7 @@ class Themes extends Checkimplementation { public $name = 'themes'; public $check_all_themes; + public $alerts = array(); public function __construct($check_all_themes) { $this->check_all_themes = $check_all_themes; @@ -25,7 +26,6 @@ public function init() { $this->score = 0; $this->result = ''; $this->label = 'Themes'; - $this->alerts = array(); self::$instance = $this; return $this; } @@ -34,6 +34,7 @@ public function run() { if (!function_exists('wp_get_themes')) { require_once \WP_CLI::get_config('path') . '/wp-includes/theme.php'; } + $current_theme = wp_get_theme(); $all_themes = Utils::sanitize_data( wp_get_themes() ); $update = Utils::sanitize_data( get_theme_updates() ); $report = array(); @@ -43,13 +44,23 @@ public function run() { $slug = substr($theme_path, 0, stripos($theme_path,'/')); } - $vulnerable = $this->is_vulnerable($slug, $data['Version']); + // Check if we only want to scan the active theme. + if (!$this->check_all_themes) { + // If theme list index doesn't match current theme, skip. + if ($current_theme->stylesheet !== $slug) { + continue; + } + } + + $data = wp_get_theme($slug); + $version = $data->version; + $vulnerable = $this->is_vulnerable($slug, $version); $needs_update = 0; $available = '-'; if (isset($update[$theme_path])) { $needs_update = 1; - $available = $update[$theme_path]->update->new_version; + $available = $update[$slug]->update["new_version"]; } if ( false === $vulnerable ) { $vulnerable = "None"; @@ -59,7 +70,7 @@ public function run() { $report[$slug] = array( 'slug' => $slug, - 'installed' => (string) $data['Version'], + 'installed' => (string) $version, 'available' => (string) $available, 'needs_update' => (string) $needs_update, 'vulnerable' => $vulnerable, @@ -121,12 +132,13 @@ protected function getThemeVulnerability($theme_slug ) } /** - * Checks a theme by slug and version for vulnerabilities - * @param $theme_slug string (required) string representing the theme slug - * @param $current_version string (required) string representing the theme version - * - * @return array containing the vulnerability or false - */ + * Checks a theme by slug and version for vulnerabilities + * @param $theme_slug string (required) string representing the theme slug + * @param $current_version string (required) string representing the theme version + * + * @return array containing the vulnerability or false + * @throws \Exception + */ public function is_vulnerable($theme_slug, $current_version) { // Fetch the theme data if we don't have it already @@ -140,7 +152,7 @@ public function is_vulnerable($theme_slug, $current_version) { } // No issues if the theme has no vulnerabilities - if ( ! isset( $theme_results['vulnerabilities'] ) || empty( $theme_results['vulnerabilities'] ) ) { + if ( empty( $theme_results['vulnerabilities'] ) ) { return false; } From 0a79d26a27948961282739cd9de23fc3518d70e2 Mon Sep 17 00:00:00 2001 From: Kyle Taylor Date: Thu, 29 Apr 2021 04:16:37 -0500 Subject: [PATCH 4/6] =?UTF-8?q?Default=20=E2=80=9Call=E2=80=9D=20command?= =?UTF-8?q?=20to=20use=20--all?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When this command runs on the platform, it does not explicitly utilize the --all flag, but that’s because the plugin command (which does have an option for --all) does not actually implement this logic - it will pull all plugins and makes no distinction whether they’re active or not. This commit will just assume that when anyone (including the platform) runs the “all” command, it will expect the --all flag is enabled. --- php/commands/launchcheck.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/commands/launchcheck.php b/php/commands/launchcheck.php index 54d6b03..0296669 100644 --- a/php/commands/launchcheck.php +++ b/php/commands/launchcheck.php @@ -38,8 +38,8 @@ public function all($args, $assoc_args) { $searcher->register( new \Pantheon\Checks\Insecure() ); $searcher->register( new \Pantheon\Checks\Exploited() ); $searcher->execute(); - $checker->register( new \Pantheon\Checks\Plugins(isset($assoc_args['all'])) ); - $checker->register( new \Pantheon\Checks\Themes(isset($assoc_args['all'])) ); + $checker->register( new \Pantheon\Checks\Plugins(TRUE)); + $checker->register( new \Pantheon\Checks\Themes(TRUE)); $checker->register( new \Pantheon\Checks\Cron() ); $checker->register( new \Pantheon\Checks\Objectcache() ); $checker->register( new \Pantheon\Checks\Database() ); From 7a2bf06bdda7c0abcea6b32ca603fd2082bd0e0f Mon Sep 17 00:00:00 2001 From: Kyle Taylor Date: Thu, 29 Apr 2021 10:22:48 -0500 Subject: [PATCH 5/6] Add encrypted WPScan API key --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 79f40cd..f3cb147 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,7 @@ cache: env: global: - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + - secure: qVuABE9laRLFk+2J5pJjmJI6YmRqEEailCvkwiN0Gqx+68KaB2t64djEnVYxWo2nxzZE7jZ0cNabQxd1mvFOWAZAvCetlKmLBfO8qoBsfMtqimWprSUA3fXqqXJ9YDmscK/zeOzM0cbnD7HbJ+bB7Zl6zHcjzTD019PD8FT3iDc= before_script: - bash bin/install-package-tests.sh From 15eaa24bb42d843ad1ba4fea0f28fd702a5151b5 Mon Sep 17 00:00:00 2001 From: Kyle Taylor Date: Thu, 29 Apr 2021 10:49:35 -0500 Subject: [PATCH 6/6] Reformat .travis.yml --- .travis.yml | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index f3cb147..f6b9db0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,45 +1,38 @@ sudo: false language: php dist: trusty - notifications: email: on_success: never on_failure: change - branches: only: - master - - "/^v[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+.*$/" - + - '/^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+.*$/' php: - 7.3 - 7.2 - cache: - composer - - "$HOME/.composer/cache" - + - $HOME/.composer/cache env: global: - - WP_CLI_BIN_DIR=/tmp/wp-cli-phar - - secure: qVuABE9laRLFk+2J5pJjmJI6YmRqEEailCvkwiN0Gqx+68KaB2t64djEnVYxWo2nxzZE7jZ0cNabQxd1mvFOWAZAvCetlKmLBfO8qoBsfMtqimWprSUA3fXqqXJ9YDmscK/zeOzM0cbnD7HbJ+bB7Zl6zHcjzTD019PD8FT3iDc= - + - WP_CLI_BIN_DIR=/tmp/wp-cli-phar + - secure: >- + qVuABE9laRLFk+2J5pJjmJI6YmRqEEailCvkwiN0Gqx+68KaB2t64djEnVYxWo2nxzZE7jZ0cNabQxd1mvFOWAZAvCetlKmLBfO8qoBsfMtqimWprSUA3fXqqXJ9YDmscK/zeOzM0cbnD7HbJ+bB7Zl6zHcjzTD019PD8FT3iDc= before_script: - bash bin/install-package-tests.sh - composer install - -script: "./vendor/bin/behat --ansi" - +script: ./vendor/bin/behat --ansi before_deploy: - bash bin/prepare.sh - deploy: provider: releases api_key: - secure: mF9U4mO+B+lJKqK6rqom/nOlsLHDRlBVgVIQxUuO4xCPuygD1eer8Hfkvqo58tpsPWF24Iqek4NyFTZ7dY78vmhVUPCxS/nq/+6A0Dyg3uqFYK5F+Sn60e46ZATSOJVDlKTr62ZR04dq0tjrFBwXfNXqv9RMQGjaOVD/U+tKTsw= + secure: >- + mF9U4mO+B+lJKqK6rqom/nOlsLHDRlBVgVIQxUuO4xCPuygD1eer8Hfkvqo58tpsPWF24Iqek4NyFTZ7dY78vmhVUPCxS/nq/+6A0Dyg3uqFYK5F+Sn60e46ZATSOJVDlKTr62ZR04dq0tjrFBwXfNXqv9RMQGjaOVD/U+tKTsw= file: wp_launch_check.phar skip_cleanup: true - on: + 'on': repo: pantheon-systems/wp_launch_check tags: true