Changeset 2452411
- Timestamp:
- 01/08/2021 10:04:19 AM (5 years ago)
- Location:
- wpscan
- Files:
-
- 20 added
- 10 deleted
- 30 edited
- 1 copied
-
tags/1.14 (copied) (copied from wpscan/trunk)
-
tags/1.14/app/Account.php (modified) (2 diffs)
-
tags/1.14/app/Checks/Check.php (modified) (2 diffs)
-
tags/1.14/app/Checks/System.php (modified) (3 diffs)
-
tags/1.14/app/Dashboard.php (modified) (1 diff)
-
tags/1.14/app/Notification.php (modified) (1 diff)
-
tags/1.14/app/Plugin.php (modified) (13 diffs)
-
tags/1.14/app/Report.php (modified) (1 diff)
-
tags/1.14/app/Settings.php (modified) (9 diffs)
-
tags/1.14/app/Summary.php (modified) (3 diffs)
-
tags/1.14/assets/css/deactivate.css (added)
-
tags/1.14/assets/css/style.css (modified) (1 diff)
-
tags/1.14/assets/js/deactivate.js (added)
-
tags/1.14/assets/js/scripts.js (modified) (2 diffs)
-
tags/1.14/assets/logo.svg (deleted)
-
tags/1.14/assets/menu-icon.svg (deleted)
-
tags/1.14/assets/scripts.js (deleted)
-
tags/1.14/assets/style.css (deleted)
-
tags/1.14/includes (deleted)
-
tags/1.14/readme.txt (modified) (3 diffs)
-
tags/1.14/security-checks/https (added)
-
tags/1.14/security-checks/https/check.php (added)
-
tags/1.14/security-checks/weak-passwords (added)
-
tags/1.14/security-checks/weak-passwords/assets (added)
-
tags/1.14/security-checks/weak-passwords/assets/passwords.txt (added)
-
tags/1.14/security-checks/weak-passwords/check.php (added)
-
tags/1.14/security-checks/xmlrpc-enabled/check.php (modified) (2 diffs)
-
tags/1.14/vendor/composer/installed.json (added)
-
tags/1.14/views/deactivate.php (added)
-
tags/1.14/views/report.php (modified) (6 diffs)
-
tags/1.14/wpscan.php (modified) (1 diff)
-
trunk/app/Account.php (modified) (2 diffs)
-
trunk/app/Checks/Check.php (modified) (2 diffs)
-
trunk/app/Checks/System.php (modified) (3 diffs)
-
trunk/app/Dashboard.php (modified) (1 diff)
-
trunk/app/Notification.php (modified) (1 diff)
-
trunk/app/Plugin.php (modified) (13 diffs)
-
trunk/app/Report.php (modified) (1 diff)
-
trunk/app/Settings.php (modified) (9 diffs)
-
trunk/app/Summary.php (modified) (3 diffs)
-
trunk/assets/css/deactivate.css (added)
-
trunk/assets/css/style.css (modified) (1 diff)
-
trunk/assets/js/deactivate.js (added)
-
trunk/assets/js/scripts.js (modified) (2 diffs)
-
trunk/assets/logo.svg (deleted)
-
trunk/assets/menu-icon.svg (deleted)
-
trunk/assets/scripts.js (deleted)
-
trunk/assets/style.css (deleted)
-
trunk/includes (deleted)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/security-checks/https (added)
-
trunk/security-checks/https/check.php (added)
-
trunk/security-checks/weak-passwords (added)
-
trunk/security-checks/weak-passwords/assets (added)
-
trunk/security-checks/weak-passwords/assets/passwords.txt (added)
-
trunk/security-checks/weak-passwords/check.php (added)
-
trunk/security-checks/xmlrpc-enabled/check.php (modified) (2 diffs)
-
trunk/vendor/composer/installed.json (added)
-
trunk/views/deactivate.php (added)
-
trunk/views/report.php (modified) (6 diffs)
-
trunk/wpscan.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
wpscan/tags/1.14/app/Account.php
r2429586 r2452411 25 25 $this->parent = $parent; 26 26 27 add_action( 'wpscan/api/get/after', array( $this, 'update_account_status' ), 10, 2 );28 27 add_action( 'admin_init', array( $this, 'add_account_summary_meta_box' ) ); 29 28 } 30 29 31 30 /** 32 * Update account status after the api request.31 * Update account status by calling the /status endpoint. 33 32 * 34 33 * @since 1.0.0 35 * @param string $endpoint endpoint. 36 * @param string $response response. 34 * @param string $api_token 37 35 * @access public 38 36 * @return void 39 37 */ 40 public function update_account_status( $endpoint, $response ) { 41 $wp_endpoit = '/wordpresses/' . str_replace( '.', '', get_bloginfo( 'version' ) ); 38 public function update_account_status( $api_token = null ) { 39 $current = get_option( $this->parent->OPT_ACCOUNT_STATUS, array() ); 40 $updated = $current; 41 42 $req = $this->parent->api_get( '/status', $api_token ); 43 44 if ( is_object( $req ) ) { 45 $updated['plan'] = $req->plan; 42 46 43 if ( $endpoint === $wp_endpoit ) { 44 $current = get_option( $this->parent->OPT_ACCOUNT_STATUS, array() ); 45 $updated = $current; 46 47 $updated['limit'] = wp_remote_retrieve_header( $response, 'x-ratelimit-limit' ); 48 $updated['remaining'] = wp_remote_retrieve_header( $response, 'x-ratelimit-remaining' ); 49 $updated['reset'] = wp_remote_retrieve_header( $response, 'x-ratelimit-reset' ); 50 51 if ( ! isset( $current['plan'] ) || $current['limit'] !== $updated['limit'] ) { 52 $req = $this->parent->api_get( '/status' ); 53 54 // Plan. 55 if ( is_object( $req ) ) { 56 $updated['plan'] = $req->plan; 57 } 58 59 // For enterprise users. 60 if ( -1 === $req->requests_remaining ) { 61 $updated['limit'] = __( 'unlimited', 'wpscan' ); 62 $updated['remaining'] = __( 'unlimited', 'wpscan' ); 63 $updated['reset'] = __( 'unlimited', 'wpscan' ); 64 } 47 // Enterprise users. 48 if ( -1 === $req->requests_remaining ) { 49 $updated['limit'] = __( 'unlimited', 'wpscan' ); 50 $updated['remaining'] = __( 'unlimited', 'wpscan' ); 51 $updated['reset'] = __( 'unlimited', 'wpscan' ); 52 } else { 53 $updated['limit'] = $req->requests_limit; 54 $updated['remaining'] = $req->requests_remaining; 55 $updated['reset'] = $req->requests_reset; 65 56 } 66 57 … … 98 89 public function get_account_status() { 99 90 $defaults = array( 100 'plan' => 'N O DATA',91 'plan' => 'None', 101 92 'limit' => 50, 102 93 'remaining' => 50, -
wpscan/tags/1.14/app/Checks/Check.php
r2429586 r2452411 112 112 final public function add_vulnerability( $title, $severity, $id ) { 113 113 $vulnerability = array( 114 'id' => $id,115 114 'title' => $title, 116 115 'severity' => $severity, 116 'id' => $id, 117 117 ); 118 118 … … 220 220 if ( is_array( $this->vulnerabilities ) ) { 221 221 $updated['security-checks'][ $this->id ]['vulnerabilities'] = $this->vulnerabilities; 222 223 $this->parent->maybe_fire_issue_found_action('security-check', $this->id, $updated['security-checks'][ $this->id ]); 222 224 } else { 223 225 $updated['security-checks'][ $this->id ]['vulnerabilities'] = array(); -
wpscan/tags/1.14/app/Checks/System.php
r2429586 r2452411 14 14 */ 15 15 class System { 16 17 public $OPT_FATAL_ERRORS = 'wpscan_fatal_errors'; 18 19 16 20 /** 17 21 * A list of registered checks. … … 35 39 public function __construct( $parent ) { 36 40 $this->parent = $parent; 41 42 register_shutdown_function( array( $this, 'catch_errors' ) ); 43 44 add_action( 'admin_notices', array( $this, 'display_errors' ) ); 37 45 38 46 add_action( 'plugins_loaded', array( $this, 'load_checks' ) ); … … 86 94 87 95 /** 96 * Register a shutdown hook to catch errors 97 * 98 * @since 1.0.0 99 * @access public 100 * @return void 101 */ 102 public function catch_errors() { 103 $error = error_get_last(); 104 105 if ($error && $error['type']) { 106 107 if ( basename($error['file']) == 'check.php' ) { 108 $errors = get_option($this->OPT_FATAL_ERRORS, array() ); 109 110 array_push( $errors, $error ); 111 112 update_option( $this->OPT_FATAL_ERRORS, array_unique( $errors ) ); 113 114 $report = $this->parent->get_report(); 115 116 $report['cache'] = strtotime( current_time( 'mysql' ) ); 117 118 update_option( $this->parent->OPT_REPORT, $report ); 119 120 $this->parent->classes['account']->update_account_status(); 121 122 delete_transient( $this->parent->WPSCAN_TRANSIENT_CRON ); 123 } 124 } 125 } 126 127 /** 128 * Display fatal errors 129 * 130 * @since 1.0.0 131 * @access public 132 * @return void 133 */ 134 public function display_errors() { 135 $screen = get_current_screen(); 136 $errors = get_option($this->OPT_FATAL_ERRORS, array() ); 137 138 139 if ( strstr( $screen->id, $this->parent->classes['report']->page ) ) { 140 foreach ($errors as $err ) { 141 $msg = explode('Stack', $err['message'])[0]; 142 $msg = trim($msg); 143 144 echo "<div class='notice notice-error'><p>$msg</p></div>"; 145 } 146 } 147 } 148 149 /** 88 150 * List vulnerabilities in the report. 89 151 * -
wpscan/tags/1.14/app/Dashboard.php
r2429586 r2452411 76 76 77 77 foreach ( $vulns as $vuln ) { 78 echo "<div><span class='dashicons dashicons-warning is-red'></span> " . esc_html($vuln) . "</div><br/>"; 78 $vuln = wp_kses( $vuln, array( 'a' => array( 'href' => array() ) ) ); // Only allow a href HTML tags. 79 echo "<div><span class='dashicons dashicons-warning is-red'></span> " . $vuln . "</div><br/>"; 79 80 } 80 81 -
wpscan/tags/1.14/app/Notification.php
r2429586 r2452411 80 80 */ 81 81 public function add_meta_box_notification() { 82 if ( $this->parent->is_wp_cron_disabled() ) { 83 return; 84 } 85 82 86 add_meta_box( 83 87 'wpscan-metabox-notification', -
wpscan/tags/1.14/app/Plugin.php
r2429586 r2452411 56 56 public $report; 57 57 58 // Action fired when an issue is found 59 public $WPSCAN_ISSUE_FOUND = 'wpscan_issue_found'; 60 58 61 /** 59 62 * Class constructor. … … 79 82 add_action( 'admin_bar_menu', array( $this, 'admin_bar' ), 65 ); 80 83 add_action( $this->WPSCAN_SCHEDULE, array( $this, 'check_now' ) ); 84 add_action( 'in_admin_header', array( $this, 'deactivate_screen' ) ); 85 86 // Check if wp cron is disabled 87 if ( $this->is_wp_cron_disabled() ) { 88 add_action( 'admin_notices', array( $this, 'wp_cron_alert' ) ); 89 } 81 90 82 91 if ( defined( 'WPSCAN_API_TOKEN' ) ) { … … 129 138 */ 130 139 public function deactivate() { 140 delete_option( $this->OPT_SCANNING_INTERVAL ); 141 142 delete_option( $this->OPT_SCANNING_TIME ); 143 131 144 wp_clear_scheduled_hook( $this->WPSCAN_SCHEDULE ); 145 } 146 147 /** 148 * Deactivate screen 149 * 150 * @since 1.14.0 151 * @access public 152 * @return void 153 */ 154 public function deactivate_screen() { 155 global $pagenow; 156 157 if ( 'plugins.php' === $pagenow ) { 158 include_once plugin_dir_path( WPSCAN_PLUGIN_FILE ) . 'views/deactivate.php'; 159 } 160 } 161 162 /** 163 * Check if WP-Cron is disabled 164 * 165 * @since 1.14.0 166 * @access public 167 * @return bool 168 */ 169 public function is_wp_cron_disabled() { 170 return defined('DISABLE_WP_CRON') && DISABLE_WP_CRON; 171 } 172 173 /** 174 * Display cron disabled alert 175 * 176 * @since 1.14.0 177 * @access public 178 * @return void 179 */ 180 public function wp_cron_alert() { 181 echo "<div class='notice notice-error'><p>". __( 'WP-Cron has been disabled in the wp-config.php file using the <code>DISABLE_WP_CRON</code> constant. Automated scans and other features that rely on cron will not work.', 'wpscan' ) ."</p></div>"; 132 182 } 133 183 … … 161 211 */ 162 212 public function admin_enqueue( $hook ) { 213 global $pagenow; 163 214 $screen = get_current_screen(); 164 215 … … 207 258 208 259 wp_localize_script('wpscan', 'wpscan', $localized); 260 } 261 262 if ( 'plugins.php' === $pagenow ) { 263 wp_enqueue_style( 264 'wpscan-deactivate', 265 plugins_url( 'assets/css/deactivate.css', WPSCAN_PLUGIN_FILE ), 266 array(), 267 $this->wpscan_plugin_version() 268 ); 269 270 wp_enqueue_script( 271 'wpscan-deactivate', 272 plugins_url( 'assets/js/deactivate.js', WPSCAN_PLUGIN_FILE ), 273 array( 'jquery' ), 274 $this->wpscan_plugin_version() 275 ); 209 276 } 210 277 } … … 387 454 388 455 // Hook before the request. 389 do_action( 'wpscan/api/get/before', $endpoint );456 //do_action( 'wpscan/api/get/before', $endpoint ); 390 457 391 458 // Start the request. … … 394 461 395 462 // Hook after the request. 396 do_action( 'wpscan/api/get/after', $endpoint, $response );463 //do_action( 'wpscan/api/get/after', $endpoint, $response ); 397 464 398 465 if ( 200 === $code ) { … … 479 546 // Reset errors. 480 547 update_option( $this->OPT_ERRORS, array() ); 548 update_option( $this->classes['checks/system']->OPT_FATAL_ERRORS, array() ); 481 549 482 550 // Plugins. 483 $ report['plugins'] = $this->verify_plugins( $ignored['plugins'] );551 $this->report['plugins'] = $this->verify_plugins( $ignored['plugins'] ); 484 552 485 553 // Themes. 486 $ report['themes'] = $this->verify_themes( $ignored['themes'] );554 $this->report['themes'] = $this->verify_themes( $ignored['themes'] ); 487 555 488 556 // WordPress. 489 557 if ( ! isset( $ignored['wordpress'] ) ) { 490 $ report['wordpress'] = $this->verify_wordpress();558 $this->report['wordpress'] = $this->verify_wordpress(); 491 559 } else { 492 $ report['wordpress'] = array();560 $this->report['wordpress'] = array(); 493 561 } 494 562 495 563 // Security checks. 496 $ report['security-checks'] = array();564 $this->report['security-checks'] = array(); 497 565 498 566 foreach ( $this->classes['checks/system']->checks as $id => $data ) { 499 567 $data['instance']->perform(); 500 $ report['security-checks'][ $id ]['vulnerabilities'] = array();568 $this->report['security-checks'][ $id ]['vulnerabilities'] = array(); 501 569 502 570 if ( $data['instance']->vulnerabilities ) { 503 $report['security-checks'][ $id ]['vulnerabilities'] = $data['instance']->get_vulnerabilities(); 571 $this->report['security-checks'][ $id ]['vulnerabilities'] = $data['instance']->get_vulnerabilities(); 572 573 $this->maybe_fire_issue_found_action('security-check', $id, $this->report['security-checks'][ $id ]); 504 574 } 505 575 } 506 576 507 577 // Caching. 508 $ report['cache'] = strtotime( current_time( 'mysql' ) );578 $this->report['cache'] = strtotime( current_time( 'mysql' ) ); 509 579 510 580 // Saving. 511 update_option( $this->OPT_REPORT, $report, true ); 581 update_option( $this->OPT_REPORT, $this->report, true ); 582 583 // Updates account status (API calls etc). 584 $this->classes['account']->update_account_status(); 585 } 586 587 /** 588 * Fires the wpscan_issue_found action if needed 589 * 590 * @since 1.14.0 591 * 592 * @param string $type - The affected component type: plugin, theme, wordpress or security-check 593 * @param string $slug - The affected component slug. 594 * For wordpress, it will be the version (ie 5.5.3) 595 * For security-checks, it will be the id of the check, ie xmlrpc-enabled 596 * @param array $details - An array containing some keys, such as vulnerabilities 597 * @param array additional_details - An array with the plugin details, such as Version etc 598 **/ 599 public function maybe_fire_issue_found_action($type, $slug, $details, $additional_details = []) { 600 if ( !count($details['vulnerabilities']) > 0) { 601 return; 602 } 603 604 do_action($this->WPSCAN_ISSUE_FOUND, $type, $slug, $details, $additional_details); 512 605 } 513 606 … … 546 639 $plugins[ $slug ]['closed'] = false; 547 640 } 641 642 $this->maybe_fire_issue_found_action('plugin', $slug, $plugins[ $slug ], $details ); 548 643 } else { 549 644 if ( 404 === $result ) { … … 596 691 $themes[ $slug ]['closed'] = false; 597 692 } 693 694 $this->maybe_fire_issue_found_action('theme', $slug, $themes[ $slug ], $details ); 598 695 } else { 599 696 if ( 404 === $result ) { … … 614 711 */ 615 712 public function verify_wordpress() { 616 $wordp erss = array();713 $wordpress = array(); 617 714 618 715 $version = get_bloginfo( 'version' ); … … 620 717 621 718 if ( is_object( $result ) ) { 622 $wordperss[ $version ]['vulnerabilities'] = $this->get_vulnerabilities( $result, $version ); 623 } 624 625 return $wordperss; 719 $wordpress[ $version ]['vulnerabilities'] = $this->get_vulnerabilities( $result, $version ); 720 721 $this->maybe_fire_issue_found_action('wordpress', $version, $wordpress[ $version ] ); 722 } 723 724 return $wordpress; 626 725 } 627 726 … … 812 911 */ 813 912 public function delete_doing_cron_transient() { 814 $option = get_option( '_transient_wpscan_doing_cron' ); 815 816 if ( $option ) { 817 delete_option( '_transient_wpscan_doing_cron' ); 818 } 913 delete_transient( $this->WPSCAN_TRANSIENT_CRON ); 819 914 } 820 915 } -
wpscan/tags/1.14/app/Report.php
r2429586 r2452411 16 16 { 17 17 // Page slug. 18 p rivate$page;18 public $page; 19 19 20 20 /** -
wpscan/tags/1.14/app/Settings.php
r2429586 r2452411 29 29 add_action( 'admin_init', array( $this, 'admin_init' ) ); 30 30 add_action( 'admin_notices', array( $this, 'got_api_token' ) ); 31 32 31 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ) ); 33 32 34 add_action( 'add_option_' . $this->parent->OPT_SCANNING_INTERVAL, array( $this, 'schedule_event' ), 10, 2 ); 35 add_action( 'update_option_' . $this->parent->OPT_SCANNING_INTERVAL, array( $this, 'schedule_event' ), 10, 3 ); 36 add_action( 'update_option_' . $this->parent->OPT_SCANNING_TIME, array( $this, 'schedule_event' ), 10, 3 ); 37 38 add_action( 'update_option_' . $this->parent->OPT_IGNORE_ITEMS, array( $this, 'update_ignored_items' ), 10, 3 ); 33 if ( ! $this->parent->is_wp_cron_disabled() ) { 34 add_action( 'add_option_' . $this->parent->OPT_SCANNING_INTERVAL, array( $this, 'schedule_event' ), 10, 2 ); 35 add_action( 'update_option_' . $this->parent->OPT_SCANNING_INTERVAL, array( $this, 'schedule_event' ), 10, 2 ); 36 add_action( 'update_option_' . $this->parent->OPT_SCANNING_TIME, array( $this, 'schedule_event' ), 10, 2 ); 37 } 38 39 add_action( 'update_option_' . $this->parent->OPT_IGNORE_ITEMS, array( $this, 'update_ignored_items' ), 10, 2 ); 39 40 } 40 41 … … 62 63 'wpscan-settings', 63 64 plugins_url( 'assets/css/settings.css', WPSCAN_PLUGIN_FILE ), 64 array(),65 $this->parent->wpscan_plugin_version()65 array(), 66 $this->parent->wpscan_plugin_version() 66 67 ); 67 68 } … … 76 77 */ 77 78 public function admin_init() { 78 register_setting( $this->page, $this->parent->OPT_API_TOKEN, array( $this, 'sanitize_api_token' ) ); 79 register_setting( $this->page, $this->parent->OPT_SCANNING_INTERVAL, 'sanitize_text_field' ); 80 register_setting( $this->page, $this->parent->OPT_SCANNING_TIME, 'sanitize_text_field' ); 79 // No need to sanitise the API token from the Settings form if we are using the token from the 80 // WPSCAN_API_TOKEN constant. register_setting() is run before WPSCAN_API_TOKEN is placed in the database, 81 // causing a NULL API token to be passed to some functions if called when using a WPSCAN_API_TOKEN constant. 82 if ( ! defined( 'WPSCAN_API_TOKEN' ) ) { 83 register_setting( $this->page, $this->parent->OPT_API_TOKEN, array( 'sanitize_callback' => array( $this, 'sanitize_api_token' ) ) ); 84 } 85 81 86 register_setting( $this->page, $this->parent->OPT_IGNORE_ITEMS ); 87 88 if ( ! $this->parent->is_wp_cron_disabled() ) { 89 register_setting( $this->page, $this->parent->OPT_SCANNING_INTERVAL, 'sanitize_text_field' ); 90 register_setting( $this->page, $this->parent->OPT_SCANNING_TIME, 'sanitize_text_field' ); 91 } 82 92 83 93 $section = $this->page . '_section'; … … 98 108 ); 99 109 100 add_settings_field( 101 $this->parent->OPT_SCANNING_INTERVAL, 102 __( 'Automated Scanning', 'wpscan' ), 103 array( $this, 'field_scanning_interval' ), 104 $this->page, 105 $section 106 ); 107 108 add_settings_field( 109 $this->parent->OPT_SCANNING_TIME, 110 __( 'Scanning Time', 'wpscan' ), 111 array( $this, 'field_scanning_time' ), 112 $this->page, 113 $section 114 ); 110 if ( ! $this->parent->is_wp_cron_disabled() ) { 111 112 add_settings_field( 113 $this->parent->OPT_SCANNING_INTERVAL, 114 __( 'Automated Scanning', 'wpscan' ), 115 array( $this, 'field_scanning_interval' ), 116 $this->page, 117 $section 118 ); 119 120 add_settings_field( 121 $this->parent->OPT_SCANNING_TIME, 122 __( 'Scanning Time', 'wpscan' ), 123 array( $this, 'field_scanning_time' ), 124 $this->page, 125 $section 126 ); 127 128 } 115 129 116 130 add_settings_field( … … 210 224 echo '</form>'; 211 225 echo '</div>'; 212 }226 } 213 227 214 228 /** … … 302 316 public function field_scanning_time() { 303 317 $opt = $this->parent->OPT_SCANNING_TIME; 304 $value = esc_attr( get_option( $opt, '12:00') );318 $value = esc_attr( get_option( $opt, date('H:i') ) ); 305 319 $disabled = $this->parent->is_interval_scanning_disabled() ? "disabled='true'" : null; 306 320 … … 367 381 : __( 'Plugins', 'wpscan' ); 368 382 369 370 383 echo "<div class='wpscan-ignore-items-section'>"; 371 384 … … 397 410 public function sanitize_api_token( $value ) { 398 411 $value = trim( $value ); 399 $result = $this->parent->api_get( '/status', $value ); 412 413 // update_account_status() calls the /status API endpoint, verifying the validity of the Token passed via $value and updates the account status if needed. 414 if ( empty( $value ) ) { 415 delete_option( $this->parent->OPT_ACCOUNT_STATUS ); 416 } else { 417 $this->parent->classes['account']->update_account_status( $value ); 418 } 400 419 401 420 $errors = get_option( $this->parent->OPT_ERRORS ); … … 432 451 if ( ! empty( $api_token ) && $old_value !== $value ) { 433 452 $interval = esc_attr( get_option( $this->parent->OPT_SCANNING_INTERVAL, 'daily' ) ); 434 $time = esc_attr( get_option( $this->parent->OPT_SCANNING_TIME, '12:00+1day' ) );453 $time = esc_attr( get_option( $this->parent->OPT_SCANNING_TIME, date('H:i') . ' +1day' ) ); 435 454 436 455 wp_clear_scheduled_hook( $this->parent->WPSCAN_SCHEDULE ); -
wpscan/tags/1.14/app/Summary.php
r2429586 r2452411 67 67 ?> 68 68 69 <?php 70 if ( ! empty( $errors ) ) { 71 foreach ( $errors as $err ) { 72 // $err should not contain user input. If you like to add an esc_html() here, be sure to update the error text that use HTML 73 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . $err . '</strong></p>'; 74 } 75 } elseif ( empty( $this->parent->get_report() ) ) { // No scan run yet. 76 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'No scan run yet!', 'wpscan' ) . '</strong></p>'; 77 } elseif ( empty( $errors ) && 0 === $total ) { 78 echo '<p class="wpscan-summary-res is-green"><span class="dashicons dashicons-awards"></span> <strong>' . __( 'No known vulnerabilities found', 'wpscan' ) . '</strong></p>'; 79 } elseif( ! get_option( $this->parent->OPT_API_TOKEN ) ) { 80 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'You need to add a WPScan API Token to the settings page', 'wpscan' ) . '</strong></p>'; 81 } else { 82 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'Some vulnerabilities were found', 'wpscan' ) . '</strong></p>'; 83 } 84 ?> 85 69 86 <p> 70 87 <?php _e( 'The last full scan was run on: ', 'wpscan' ) ?> … … 84 101 </p> 85 102 86 <?php 87 // Only show next scan time if there's a scheduled cron job. 88 if ( wp_next_scheduled( $this->parent->WPSCAN_SCHEDULE ) ) { 89 ?> 103 <?php if ( ! $this->parent->is_wp_cron_disabled() && wp_next_scheduled( $this->parent->WPSCAN_SCHEDULE ) ) { ?> 90 104 <p> 91 105 <?php _e( 'The next scan will automatically be run on ', 'wpscan' ) ?> … … 96 110 <?php } ?> 97 111 98 <?php 99 if ( ! empty( $errors ) ) { 100 foreach ( $errors as $err ) { 101 // $err should not contain user input. If you like to add an esc_html() here, be sure to update the error text that use HTML 102 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . $err . '</strong></p>'; 112 <p class="description"> 113 <?php 114 if ( get_option( $this->parent->OPT_API_TOKEN ) ) { 115 _e( 'Click the Run All button to run a full vulnerability scan against your WordPress website.', 'wpscan' ); 116 } else { 117 _e( 'Add your API token to the settings page to be able to run a full scan.', 'wpscan' ); 103 118 } 104 } elseif ( empty( $this->parent->get_report() ) ) { // No scan run yet. 105 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'No scan run yet!', 'wpscan' ) . '</strong></p>'; 106 } elseif ( empty( $errors ) && 0 === $total ) { 107 echo '<p class="wpscan-summary-res is-green"><span class="dashicons dashicons-awards"></span> <strong>' . __( 'No known vulnerabilities found', 'wpscan' ) . '</strong></p>'; 108 } elseif( ! get_option($this->parent->OPT_API_TOKEN) ) { 109 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'You need to add a WPScan API Token to the settings page', 'wpscan' ) . '</strong></p>'; 110 } else { 111 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'Some vulnerabilities were found', 'wpscan' ) . '</strong></p>'; 112 } 113 ?> 114 115 <p class="description"> 116 <?php _e( 'Click the Run All button to run a full vulnerability scan against your WordPress website.', 'wpscan' ) ?> 119 ?> 117 120 </p> 118 121 -
wpscan/tags/1.14/assets/css/style.css
r2417112 r2452411 10 10 margin-bottom: 5px; 11 11 margin-right: 12px; 12 white-space: normal !important; 13 } 14 15 .column-name { 16 word-break: break-word; 17 width: 250px; 12 18 } 13 19 -
wpscan/tags/1.14/assets/js/scripts.js
r2424629 r2452411 32 32 success: function( ) { 33 33 check_cron(); 34 }, 35 error: function () { 36 location.reload(); 34 37 } 35 38 } ); … … 56 59 }, 57 60 error: function ( ) { 58 check_cron();61 location.reload(); 59 62 } 60 63 } ); -
wpscan/tags/1.14/readme.txt
r2433081 r2452411 3 3 Tags: wpscan, wpvulndb, security, vulnerability, hack, scan, exploit, secure, alerts 4 4 Requires at least: 3.4 5 Tested up to: 5. 5.36 Stable tag: 1.1 3.25 Tested up to: 5.6 6 Stable tag: 1.14 7 7 Requires PHP: 5.5 8 8 License: GPLv3 … … 48 48 4. Save the API token to the WPScan settings page or within the wp-config.php file 49 49 50 == F AQ==50 == Frequently Asked Questions == 51 51 52 * How many API calls are made? 52 = How many API calls are made? = 53 53 54 54 There is one API call made for the WordPress version, one call for each installed plugin and one for each theme. By default there is one scan per day. The number of daily scans can be configured when configuring notifications. 55 55 56 * How can I configure the API token in the wp-config.php file? 56 = How can I configure the API token in the wp-config.php file? = 57 57 58 58 To configure your API token in the wp-config.php file, use the following PHP code: `define( 'WPSCAN_API_TOKEN', '$your_api_token' );` 59 59 60 * How do I disable vulnerability scanning altogether? 60 = How do I disable vulnerability scanning altogether? = 61 61 62 62 You can set the following PHP constant in the wp-config.php file to disable scanning; `define( 'WPSCAN_DISABLE_SCANNING_INTERVAL', true );`. 63 63 64 * Why is the "Summary" section and the "Run All" button not showing? 64 = Why is the "Summary" section and the "Run All" button not showing? = 65 65 66 66 The cron job did not run, which can be due to: … … 78 78 79 79 == Changelog == 80 81 = 1.14 = 82 83 * Uses the status endpoint to get account data 84 * Fixes the account status not being updated unless a scan is performed when the API token is updated/set 85 * Adds vulnerability found hook 86 * New security check: Check for weak user passwords 87 * New security check: HTTPS 88 * Clear plan info if API Token set to null 89 * Fixes automated scanning when plugin deactivated and reactivated 90 * Fixes cron job not being created when using the WPSCAN_API_TOKEN constant 91 * Change default scanning time to the current time 92 * Many other small improvements 80 93 81 94 = 1.13.2 = -
wpscan/tags/1.14/security-checks/xmlrpc-enabled/check.php
r2433081 r2452411 76 76 } else { 77 77 if ( preg_match( '/<string>Incorrect username or password.<\/string>/', $authenticated_response['body'] ) ) { 78 $this->add_vulnerability( __( 'The XML-RPC interface is enabled. This significantly increases your site\'s attack surface .', 'wpscan' ), 'medium', sanitize_title( $url ) );78 $this->add_vulnerability( __( 'The XML-RPC interface is enabled. This significantly increases your site\'s attack surface', 'wpscan' ), 'medium', sanitize_title( $url ) ); 79 79 return; 80 80 } else { … … 84 84 85 85 if ( preg_match( '/<string>Hello!<\/string>/', $unauthenticated_response['body'] ) ) { 86 $this->add_vulnerability( __( 'The XML-RPC interface is partly disabled, but still allows unauthenticated requests .', 'wpscan' ), 'low', sanitize_title( $url ) );86 $this->add_vulnerability( __( 'The XML-RPC interface is partly disabled, but still allows unauthenticated requests', 'wpscan' ), 'low', sanitize_title( $url ) ); 87 87 } 88 88 } -
wpscan/tags/1.14/views/report.php
r2429586 r2452411 8 8 9 9 <div class="wrap"> 10 <?php echo file_get_contents($this->parent->plugin_dir. 'assets/svg/logo.svg'); ?> 10 <h1> 11 <?php echo file_get_contents($this->parent->plugin_dir. 'assets/svg/logo.svg'); ?> 12 </h1> 11 13 12 14 <hr class="wp-header-end"> … … 41 43 <tr> 42 44 <td scope="col" class="manage-column check-column"> </td> 43 <th scope="col" class="manage-column column-name column-primary" width="250"><?php _e( 'Name', 'wpscan' ) ?></th>45 <th scope="col" class="manage-column column-name column-primary"><?php _e( 'Name', 'wpscan' ) ?></th> 44 46 <th scope="col" class="manage-column column-description"><?php _e( 'Vulnerabilities', 'wpscan' ) ?></th> 45 47 </tr> … … 76 78 <tr> 77 79 <td scope="col" class="manage-column check-column"> </td> 78 <th scope="col" class="manage-column column-name column-primary" width="250"><?php _e( 'Name', 'wpscan' ) ?></th>80 <th scope="col" class="manage-column column-name column-primary"><?php _e( 'Name', 'wpscan' ) ?></th> 79 81 <th scope="col" class="manage-column column-description"><?php _e( 'Vulnerabilities', 'wpscan' ) ?></th> 80 82 </tr> … … 83 85 <?php 84 86 foreach ( get_plugins() as $name => $details ) { 85 $slug = $this->parent->get_plugin_slug( $name, $details );87 $slug = $this->parent->get_plugin_slug( $name, $details ); 86 88 $is_closed = $this->is_item_closed('plugins', $slug); 87 89 ?> … … 124 126 <tr> 125 127 <td scope="col" class="manage-column check-column"> </td> 126 <th scope="col" class="manage-column column-name column-primary" width="250"><?php _e( 'Name', 'wpscan' ) ?></th>128 <th scope="col" class="manage-column column-name column-primary"><?php _e( 'Name', 'wpscan' ) ?></th> 127 129 <th scope="col" class="manage-column column-description"><?php _e( 'Vulnerabilities', 'wpscan' ) ?></th> 128 130 </tr> … … 168 170 <tr> 169 171 <td scope="col" class="manage-column check-column"></td> 170 <th scope="col" class="manage-column column-name column-primary" width="250"><?php _e('Name', 'wpscan') ?></th>172 <th scope="col" class="manage-column column-name column-primary"><?php _e('Name', 'wpscan') ?></th> 171 173 <th scope="col" class="manage-column column-description"><?php _e('Result', 'wpscan') ?></th> 172 174 <th scope="col" class="manage-column column-description"><?php _e('Actions', 'wpscan') ?></th> -
wpscan/tags/1.14/wpscan.php
r2433081 r2452411 4 4 * Plugin URI: http://wordpress.org/plugins/wpscan/ 5 5 * Description: WPScan WordPress Security Scanner. Scans your system for security vulnerabilities listed in the WPScan Vulnerability Database. 6 * Version: 1.1 3.26 * Version: 1.14 7 7 * Author: WPScan Team 8 8 * Author URI: https://wpscan.com/ -
wpscan/trunk/app/Account.php
r2429586 r2452411 25 25 $this->parent = $parent; 26 26 27 add_action( 'wpscan/api/get/after', array( $this, 'update_account_status' ), 10, 2 );28 27 add_action( 'admin_init', array( $this, 'add_account_summary_meta_box' ) ); 29 28 } 30 29 31 30 /** 32 * Update account status after the api request.31 * Update account status by calling the /status endpoint. 33 32 * 34 33 * @since 1.0.0 35 * @param string $endpoint endpoint. 36 * @param string $response response. 34 * @param string $api_token 37 35 * @access public 38 36 * @return void 39 37 */ 40 public function update_account_status( $endpoint, $response ) { 41 $wp_endpoit = '/wordpresses/' . str_replace( '.', '', get_bloginfo( 'version' ) ); 38 public function update_account_status( $api_token = null ) { 39 $current = get_option( $this->parent->OPT_ACCOUNT_STATUS, array() ); 40 $updated = $current; 41 42 $req = $this->parent->api_get( '/status', $api_token ); 43 44 if ( is_object( $req ) ) { 45 $updated['plan'] = $req->plan; 42 46 43 if ( $endpoint === $wp_endpoit ) { 44 $current = get_option( $this->parent->OPT_ACCOUNT_STATUS, array() ); 45 $updated = $current; 46 47 $updated['limit'] = wp_remote_retrieve_header( $response, 'x-ratelimit-limit' ); 48 $updated['remaining'] = wp_remote_retrieve_header( $response, 'x-ratelimit-remaining' ); 49 $updated['reset'] = wp_remote_retrieve_header( $response, 'x-ratelimit-reset' ); 50 51 if ( ! isset( $current['plan'] ) || $current['limit'] !== $updated['limit'] ) { 52 $req = $this->parent->api_get( '/status' ); 53 54 // Plan. 55 if ( is_object( $req ) ) { 56 $updated['plan'] = $req->plan; 57 } 58 59 // For enterprise users. 60 if ( -1 === $req->requests_remaining ) { 61 $updated['limit'] = __( 'unlimited', 'wpscan' ); 62 $updated['remaining'] = __( 'unlimited', 'wpscan' ); 63 $updated['reset'] = __( 'unlimited', 'wpscan' ); 64 } 47 // Enterprise users. 48 if ( -1 === $req->requests_remaining ) { 49 $updated['limit'] = __( 'unlimited', 'wpscan' ); 50 $updated['remaining'] = __( 'unlimited', 'wpscan' ); 51 $updated['reset'] = __( 'unlimited', 'wpscan' ); 52 } else { 53 $updated['limit'] = $req->requests_limit; 54 $updated['remaining'] = $req->requests_remaining; 55 $updated['reset'] = $req->requests_reset; 65 56 } 66 57 … … 98 89 public function get_account_status() { 99 90 $defaults = array( 100 'plan' => 'N O DATA',91 'plan' => 'None', 101 92 'limit' => 50, 102 93 'remaining' => 50, -
wpscan/trunk/app/Checks/Check.php
r2429586 r2452411 112 112 final public function add_vulnerability( $title, $severity, $id ) { 113 113 $vulnerability = array( 114 'id' => $id,115 114 'title' => $title, 116 115 'severity' => $severity, 116 'id' => $id, 117 117 ); 118 118 … … 220 220 if ( is_array( $this->vulnerabilities ) ) { 221 221 $updated['security-checks'][ $this->id ]['vulnerabilities'] = $this->vulnerabilities; 222 223 $this->parent->maybe_fire_issue_found_action('security-check', $this->id, $updated['security-checks'][ $this->id ]); 222 224 } else { 223 225 $updated['security-checks'][ $this->id ]['vulnerabilities'] = array(); -
wpscan/trunk/app/Checks/System.php
r2429586 r2452411 14 14 */ 15 15 class System { 16 17 public $OPT_FATAL_ERRORS = 'wpscan_fatal_errors'; 18 19 16 20 /** 17 21 * A list of registered checks. … … 35 39 public function __construct( $parent ) { 36 40 $this->parent = $parent; 41 42 register_shutdown_function( array( $this, 'catch_errors' ) ); 43 44 add_action( 'admin_notices', array( $this, 'display_errors' ) ); 37 45 38 46 add_action( 'plugins_loaded', array( $this, 'load_checks' ) ); … … 86 94 87 95 /** 96 * Register a shutdown hook to catch errors 97 * 98 * @since 1.0.0 99 * @access public 100 * @return void 101 */ 102 public function catch_errors() { 103 $error = error_get_last(); 104 105 if ($error && $error['type']) { 106 107 if ( basename($error['file']) == 'check.php' ) { 108 $errors = get_option($this->OPT_FATAL_ERRORS, array() ); 109 110 array_push( $errors, $error ); 111 112 update_option( $this->OPT_FATAL_ERRORS, array_unique( $errors ) ); 113 114 $report = $this->parent->get_report(); 115 116 $report['cache'] = strtotime( current_time( 'mysql' ) ); 117 118 update_option( $this->parent->OPT_REPORT, $report ); 119 120 $this->parent->classes['account']->update_account_status(); 121 122 delete_transient( $this->parent->WPSCAN_TRANSIENT_CRON ); 123 } 124 } 125 } 126 127 /** 128 * Display fatal errors 129 * 130 * @since 1.0.0 131 * @access public 132 * @return void 133 */ 134 public function display_errors() { 135 $screen = get_current_screen(); 136 $errors = get_option($this->OPT_FATAL_ERRORS, array() ); 137 138 139 if ( strstr( $screen->id, $this->parent->classes['report']->page ) ) { 140 foreach ($errors as $err ) { 141 $msg = explode('Stack', $err['message'])[0]; 142 $msg = trim($msg); 143 144 echo "<div class='notice notice-error'><p>$msg</p></div>"; 145 } 146 } 147 } 148 149 /** 88 150 * List vulnerabilities in the report. 89 151 * -
wpscan/trunk/app/Dashboard.php
r2429586 r2452411 76 76 77 77 foreach ( $vulns as $vuln ) { 78 echo "<div><span class='dashicons dashicons-warning is-red'></span> " . esc_html($vuln) . "</div><br/>"; 78 $vuln = wp_kses( $vuln, array( 'a' => array( 'href' => array() ) ) ); // Only allow a href HTML tags. 79 echo "<div><span class='dashicons dashicons-warning is-red'></span> " . $vuln . "</div><br/>"; 79 80 } 80 81 -
wpscan/trunk/app/Notification.php
r2429586 r2452411 80 80 */ 81 81 public function add_meta_box_notification() { 82 if ( $this->parent->is_wp_cron_disabled() ) { 83 return; 84 } 85 82 86 add_meta_box( 83 87 'wpscan-metabox-notification', -
wpscan/trunk/app/Plugin.php
r2429586 r2452411 56 56 public $report; 57 57 58 // Action fired when an issue is found 59 public $WPSCAN_ISSUE_FOUND = 'wpscan_issue_found'; 60 58 61 /** 59 62 * Class constructor. … … 79 82 add_action( 'admin_bar_menu', array( $this, 'admin_bar' ), 65 ); 80 83 add_action( $this->WPSCAN_SCHEDULE, array( $this, 'check_now' ) ); 84 add_action( 'in_admin_header', array( $this, 'deactivate_screen' ) ); 85 86 // Check if wp cron is disabled 87 if ( $this->is_wp_cron_disabled() ) { 88 add_action( 'admin_notices', array( $this, 'wp_cron_alert' ) ); 89 } 81 90 82 91 if ( defined( 'WPSCAN_API_TOKEN' ) ) { … … 129 138 */ 130 139 public function deactivate() { 140 delete_option( $this->OPT_SCANNING_INTERVAL ); 141 142 delete_option( $this->OPT_SCANNING_TIME ); 143 131 144 wp_clear_scheduled_hook( $this->WPSCAN_SCHEDULE ); 145 } 146 147 /** 148 * Deactivate screen 149 * 150 * @since 1.14.0 151 * @access public 152 * @return void 153 */ 154 public function deactivate_screen() { 155 global $pagenow; 156 157 if ( 'plugins.php' === $pagenow ) { 158 include_once plugin_dir_path( WPSCAN_PLUGIN_FILE ) . 'views/deactivate.php'; 159 } 160 } 161 162 /** 163 * Check if WP-Cron is disabled 164 * 165 * @since 1.14.0 166 * @access public 167 * @return bool 168 */ 169 public function is_wp_cron_disabled() { 170 return defined('DISABLE_WP_CRON') && DISABLE_WP_CRON; 171 } 172 173 /** 174 * Display cron disabled alert 175 * 176 * @since 1.14.0 177 * @access public 178 * @return void 179 */ 180 public function wp_cron_alert() { 181 echo "<div class='notice notice-error'><p>". __( 'WP-Cron has been disabled in the wp-config.php file using the <code>DISABLE_WP_CRON</code> constant. Automated scans and other features that rely on cron will not work.', 'wpscan' ) ."</p></div>"; 132 182 } 133 183 … … 161 211 */ 162 212 public function admin_enqueue( $hook ) { 213 global $pagenow; 163 214 $screen = get_current_screen(); 164 215 … … 207 258 208 259 wp_localize_script('wpscan', 'wpscan', $localized); 260 } 261 262 if ( 'plugins.php' === $pagenow ) { 263 wp_enqueue_style( 264 'wpscan-deactivate', 265 plugins_url( 'assets/css/deactivate.css', WPSCAN_PLUGIN_FILE ), 266 array(), 267 $this->wpscan_plugin_version() 268 ); 269 270 wp_enqueue_script( 271 'wpscan-deactivate', 272 plugins_url( 'assets/js/deactivate.js', WPSCAN_PLUGIN_FILE ), 273 array( 'jquery' ), 274 $this->wpscan_plugin_version() 275 ); 209 276 } 210 277 } … … 387 454 388 455 // Hook before the request. 389 do_action( 'wpscan/api/get/before', $endpoint );456 //do_action( 'wpscan/api/get/before', $endpoint ); 390 457 391 458 // Start the request. … … 394 461 395 462 // Hook after the request. 396 do_action( 'wpscan/api/get/after', $endpoint, $response );463 //do_action( 'wpscan/api/get/after', $endpoint, $response ); 397 464 398 465 if ( 200 === $code ) { … … 479 546 // Reset errors. 480 547 update_option( $this->OPT_ERRORS, array() ); 548 update_option( $this->classes['checks/system']->OPT_FATAL_ERRORS, array() ); 481 549 482 550 // Plugins. 483 $ report['plugins'] = $this->verify_plugins( $ignored['plugins'] );551 $this->report['plugins'] = $this->verify_plugins( $ignored['plugins'] ); 484 552 485 553 // Themes. 486 $ report['themes'] = $this->verify_themes( $ignored['themes'] );554 $this->report['themes'] = $this->verify_themes( $ignored['themes'] ); 487 555 488 556 // WordPress. 489 557 if ( ! isset( $ignored['wordpress'] ) ) { 490 $ report['wordpress'] = $this->verify_wordpress();558 $this->report['wordpress'] = $this->verify_wordpress(); 491 559 } else { 492 $ report['wordpress'] = array();560 $this->report['wordpress'] = array(); 493 561 } 494 562 495 563 // Security checks. 496 $ report['security-checks'] = array();564 $this->report['security-checks'] = array(); 497 565 498 566 foreach ( $this->classes['checks/system']->checks as $id => $data ) { 499 567 $data['instance']->perform(); 500 $ report['security-checks'][ $id ]['vulnerabilities'] = array();568 $this->report['security-checks'][ $id ]['vulnerabilities'] = array(); 501 569 502 570 if ( $data['instance']->vulnerabilities ) { 503 $report['security-checks'][ $id ]['vulnerabilities'] = $data['instance']->get_vulnerabilities(); 571 $this->report['security-checks'][ $id ]['vulnerabilities'] = $data['instance']->get_vulnerabilities(); 572 573 $this->maybe_fire_issue_found_action('security-check', $id, $this->report['security-checks'][ $id ]); 504 574 } 505 575 } 506 576 507 577 // Caching. 508 $ report['cache'] = strtotime( current_time( 'mysql' ) );578 $this->report['cache'] = strtotime( current_time( 'mysql' ) ); 509 579 510 580 // Saving. 511 update_option( $this->OPT_REPORT, $report, true ); 581 update_option( $this->OPT_REPORT, $this->report, true ); 582 583 // Updates account status (API calls etc). 584 $this->classes['account']->update_account_status(); 585 } 586 587 /** 588 * Fires the wpscan_issue_found action if needed 589 * 590 * @since 1.14.0 591 * 592 * @param string $type - The affected component type: plugin, theme, wordpress or security-check 593 * @param string $slug - The affected component slug. 594 * For wordpress, it will be the version (ie 5.5.3) 595 * For security-checks, it will be the id of the check, ie xmlrpc-enabled 596 * @param array $details - An array containing some keys, such as vulnerabilities 597 * @param array additional_details - An array with the plugin details, such as Version etc 598 **/ 599 public function maybe_fire_issue_found_action($type, $slug, $details, $additional_details = []) { 600 if ( !count($details['vulnerabilities']) > 0) { 601 return; 602 } 603 604 do_action($this->WPSCAN_ISSUE_FOUND, $type, $slug, $details, $additional_details); 512 605 } 513 606 … … 546 639 $plugins[ $slug ]['closed'] = false; 547 640 } 641 642 $this->maybe_fire_issue_found_action('plugin', $slug, $plugins[ $slug ], $details ); 548 643 } else { 549 644 if ( 404 === $result ) { … … 596 691 $themes[ $slug ]['closed'] = false; 597 692 } 693 694 $this->maybe_fire_issue_found_action('theme', $slug, $themes[ $slug ], $details ); 598 695 } else { 599 696 if ( 404 === $result ) { … … 614 711 */ 615 712 public function verify_wordpress() { 616 $wordp erss = array();713 $wordpress = array(); 617 714 618 715 $version = get_bloginfo( 'version' ); … … 620 717 621 718 if ( is_object( $result ) ) { 622 $wordperss[ $version ]['vulnerabilities'] = $this->get_vulnerabilities( $result, $version ); 623 } 624 625 return $wordperss; 719 $wordpress[ $version ]['vulnerabilities'] = $this->get_vulnerabilities( $result, $version ); 720 721 $this->maybe_fire_issue_found_action('wordpress', $version, $wordpress[ $version ] ); 722 } 723 724 return $wordpress; 626 725 } 627 726 … … 812 911 */ 813 912 public function delete_doing_cron_transient() { 814 $option = get_option( '_transient_wpscan_doing_cron' ); 815 816 if ( $option ) { 817 delete_option( '_transient_wpscan_doing_cron' ); 818 } 913 delete_transient( $this->WPSCAN_TRANSIENT_CRON ); 819 914 } 820 915 } -
wpscan/trunk/app/Report.php
r2429586 r2452411 16 16 { 17 17 // Page slug. 18 p rivate$page;18 public $page; 19 19 20 20 /** -
wpscan/trunk/app/Settings.php
r2429586 r2452411 29 29 add_action( 'admin_init', array( $this, 'admin_init' ) ); 30 30 add_action( 'admin_notices', array( $this, 'got_api_token' ) ); 31 32 31 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ) ); 33 32 34 add_action( 'add_option_' . $this->parent->OPT_SCANNING_INTERVAL, array( $this, 'schedule_event' ), 10, 2 ); 35 add_action( 'update_option_' . $this->parent->OPT_SCANNING_INTERVAL, array( $this, 'schedule_event' ), 10, 3 ); 36 add_action( 'update_option_' . $this->parent->OPT_SCANNING_TIME, array( $this, 'schedule_event' ), 10, 3 ); 37 38 add_action( 'update_option_' . $this->parent->OPT_IGNORE_ITEMS, array( $this, 'update_ignored_items' ), 10, 3 ); 33 if ( ! $this->parent->is_wp_cron_disabled() ) { 34 add_action( 'add_option_' . $this->parent->OPT_SCANNING_INTERVAL, array( $this, 'schedule_event' ), 10, 2 ); 35 add_action( 'update_option_' . $this->parent->OPT_SCANNING_INTERVAL, array( $this, 'schedule_event' ), 10, 2 ); 36 add_action( 'update_option_' . $this->parent->OPT_SCANNING_TIME, array( $this, 'schedule_event' ), 10, 2 ); 37 } 38 39 add_action( 'update_option_' . $this->parent->OPT_IGNORE_ITEMS, array( $this, 'update_ignored_items' ), 10, 2 ); 39 40 } 40 41 … … 62 63 'wpscan-settings', 63 64 plugins_url( 'assets/css/settings.css', WPSCAN_PLUGIN_FILE ), 64 array(),65 $this->parent->wpscan_plugin_version()65 array(), 66 $this->parent->wpscan_plugin_version() 66 67 ); 67 68 } … … 76 77 */ 77 78 public function admin_init() { 78 register_setting( $this->page, $this->parent->OPT_API_TOKEN, array( $this, 'sanitize_api_token' ) ); 79 register_setting( $this->page, $this->parent->OPT_SCANNING_INTERVAL, 'sanitize_text_field' ); 80 register_setting( $this->page, $this->parent->OPT_SCANNING_TIME, 'sanitize_text_field' ); 79 // No need to sanitise the API token from the Settings form if we are using the token from the 80 // WPSCAN_API_TOKEN constant. register_setting() is run before WPSCAN_API_TOKEN is placed in the database, 81 // causing a NULL API token to be passed to some functions if called when using a WPSCAN_API_TOKEN constant. 82 if ( ! defined( 'WPSCAN_API_TOKEN' ) ) { 83 register_setting( $this->page, $this->parent->OPT_API_TOKEN, array( 'sanitize_callback' => array( $this, 'sanitize_api_token' ) ) ); 84 } 85 81 86 register_setting( $this->page, $this->parent->OPT_IGNORE_ITEMS ); 87 88 if ( ! $this->parent->is_wp_cron_disabled() ) { 89 register_setting( $this->page, $this->parent->OPT_SCANNING_INTERVAL, 'sanitize_text_field' ); 90 register_setting( $this->page, $this->parent->OPT_SCANNING_TIME, 'sanitize_text_field' ); 91 } 82 92 83 93 $section = $this->page . '_section'; … … 98 108 ); 99 109 100 add_settings_field( 101 $this->parent->OPT_SCANNING_INTERVAL, 102 __( 'Automated Scanning', 'wpscan' ), 103 array( $this, 'field_scanning_interval' ), 104 $this->page, 105 $section 106 ); 107 108 add_settings_field( 109 $this->parent->OPT_SCANNING_TIME, 110 __( 'Scanning Time', 'wpscan' ), 111 array( $this, 'field_scanning_time' ), 112 $this->page, 113 $section 114 ); 110 if ( ! $this->parent->is_wp_cron_disabled() ) { 111 112 add_settings_field( 113 $this->parent->OPT_SCANNING_INTERVAL, 114 __( 'Automated Scanning', 'wpscan' ), 115 array( $this, 'field_scanning_interval' ), 116 $this->page, 117 $section 118 ); 119 120 add_settings_field( 121 $this->parent->OPT_SCANNING_TIME, 122 __( 'Scanning Time', 'wpscan' ), 123 array( $this, 'field_scanning_time' ), 124 $this->page, 125 $section 126 ); 127 128 } 115 129 116 130 add_settings_field( … … 210 224 echo '</form>'; 211 225 echo '</div>'; 212 }226 } 213 227 214 228 /** … … 302 316 public function field_scanning_time() { 303 317 $opt = $this->parent->OPT_SCANNING_TIME; 304 $value = esc_attr( get_option( $opt, '12:00') );318 $value = esc_attr( get_option( $opt, date('H:i') ) ); 305 319 $disabled = $this->parent->is_interval_scanning_disabled() ? "disabled='true'" : null; 306 320 … … 367 381 : __( 'Plugins', 'wpscan' ); 368 382 369 370 383 echo "<div class='wpscan-ignore-items-section'>"; 371 384 … … 397 410 public function sanitize_api_token( $value ) { 398 411 $value = trim( $value ); 399 $result = $this->parent->api_get( '/status', $value ); 412 413 // update_account_status() calls the /status API endpoint, verifying the validity of the Token passed via $value and updates the account status if needed. 414 if ( empty( $value ) ) { 415 delete_option( $this->parent->OPT_ACCOUNT_STATUS ); 416 } else { 417 $this->parent->classes['account']->update_account_status( $value ); 418 } 400 419 401 420 $errors = get_option( $this->parent->OPT_ERRORS ); … … 432 451 if ( ! empty( $api_token ) && $old_value !== $value ) { 433 452 $interval = esc_attr( get_option( $this->parent->OPT_SCANNING_INTERVAL, 'daily' ) ); 434 $time = esc_attr( get_option( $this->parent->OPT_SCANNING_TIME, '12:00+1day' ) );453 $time = esc_attr( get_option( $this->parent->OPT_SCANNING_TIME, date('H:i') . ' +1day' ) ); 435 454 436 455 wp_clear_scheduled_hook( $this->parent->WPSCAN_SCHEDULE ); -
wpscan/trunk/app/Summary.php
r2429586 r2452411 67 67 ?> 68 68 69 <?php 70 if ( ! empty( $errors ) ) { 71 foreach ( $errors as $err ) { 72 // $err should not contain user input. If you like to add an esc_html() here, be sure to update the error text that use HTML 73 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . $err . '</strong></p>'; 74 } 75 } elseif ( empty( $this->parent->get_report() ) ) { // No scan run yet. 76 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'No scan run yet!', 'wpscan' ) . '</strong></p>'; 77 } elseif ( empty( $errors ) && 0 === $total ) { 78 echo '<p class="wpscan-summary-res is-green"><span class="dashicons dashicons-awards"></span> <strong>' . __( 'No known vulnerabilities found', 'wpscan' ) . '</strong></p>'; 79 } elseif( ! get_option( $this->parent->OPT_API_TOKEN ) ) { 80 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'You need to add a WPScan API Token to the settings page', 'wpscan' ) . '</strong></p>'; 81 } else { 82 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'Some vulnerabilities were found', 'wpscan' ) . '</strong></p>'; 83 } 84 ?> 85 69 86 <p> 70 87 <?php _e( 'The last full scan was run on: ', 'wpscan' ) ?> … … 84 101 </p> 85 102 86 <?php 87 // Only show next scan time if there's a scheduled cron job. 88 if ( wp_next_scheduled( $this->parent->WPSCAN_SCHEDULE ) ) { 89 ?> 103 <?php if ( ! $this->parent->is_wp_cron_disabled() && wp_next_scheduled( $this->parent->WPSCAN_SCHEDULE ) ) { ?> 90 104 <p> 91 105 <?php _e( 'The next scan will automatically be run on ', 'wpscan' ) ?> … … 96 110 <?php } ?> 97 111 98 <?php 99 if ( ! empty( $errors ) ) { 100 foreach ( $errors as $err ) { 101 // $err should not contain user input. If you like to add an esc_html() here, be sure to update the error text that use HTML 102 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . $err . '</strong></p>'; 112 <p class="description"> 113 <?php 114 if ( get_option( $this->parent->OPT_API_TOKEN ) ) { 115 _e( 'Click the Run All button to run a full vulnerability scan against your WordPress website.', 'wpscan' ); 116 } else { 117 _e( 'Add your API token to the settings page to be able to run a full scan.', 'wpscan' ); 103 118 } 104 } elseif ( empty( $this->parent->get_report() ) ) { // No scan run yet. 105 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'No scan run yet!', 'wpscan' ) . '</strong></p>'; 106 } elseif ( empty( $errors ) && 0 === $total ) { 107 echo '<p class="wpscan-summary-res is-green"><span class="dashicons dashicons-awards"></span> <strong>' . __( 'No known vulnerabilities found', 'wpscan' ) . '</strong></p>'; 108 } elseif( ! get_option($this->parent->OPT_API_TOKEN) ) { 109 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'You need to add a WPScan API Token to the settings page', 'wpscan' ) . '</strong></p>'; 110 } else { 111 echo '<p class="wpscan-summary-res is-red"><span class="dashicons dashicons-megaphone"></span> <strong>' . __( 'Some vulnerabilities were found', 'wpscan' ) . '</strong></p>'; 112 } 113 ?> 114 115 <p class="description"> 116 <?php _e( 'Click the Run All button to run a full vulnerability scan against your WordPress website.', 'wpscan' ) ?> 119 ?> 117 120 </p> 118 121 -
wpscan/trunk/assets/css/style.css
r2417112 r2452411 10 10 margin-bottom: 5px; 11 11 margin-right: 12px; 12 white-space: normal !important; 13 } 14 15 .column-name { 16 word-break: break-word; 17 width: 250px; 12 18 } 13 19 -
wpscan/trunk/assets/js/scripts.js
r2424629 r2452411 32 32 success: function( ) { 33 33 check_cron(); 34 }, 35 error: function () { 36 location.reload(); 34 37 } 35 38 } ); … … 56 59 }, 57 60 error: function ( ) { 58 check_cron();61 location.reload(); 59 62 } 60 63 } ); -
wpscan/trunk/readme.txt
r2433081 r2452411 3 3 Tags: wpscan, wpvulndb, security, vulnerability, hack, scan, exploit, secure, alerts 4 4 Requires at least: 3.4 5 Tested up to: 5. 5.36 Stable tag: 1.1 3.25 Tested up to: 5.6 6 Stable tag: 1.14 7 7 Requires PHP: 5.5 8 8 License: GPLv3 … … 48 48 4. Save the API token to the WPScan settings page or within the wp-config.php file 49 49 50 == F AQ==50 == Frequently Asked Questions == 51 51 52 * How many API calls are made? 52 = How many API calls are made? = 53 53 54 54 There is one API call made for the WordPress version, one call for each installed plugin and one for each theme. By default there is one scan per day. The number of daily scans can be configured when configuring notifications. 55 55 56 * How can I configure the API token in the wp-config.php file? 56 = How can I configure the API token in the wp-config.php file? = 57 57 58 58 To configure your API token in the wp-config.php file, use the following PHP code: `define( 'WPSCAN_API_TOKEN', '$your_api_token' );` 59 59 60 * How do I disable vulnerability scanning altogether? 60 = How do I disable vulnerability scanning altogether? = 61 61 62 62 You can set the following PHP constant in the wp-config.php file to disable scanning; `define( 'WPSCAN_DISABLE_SCANNING_INTERVAL', true );`. 63 63 64 * Why is the "Summary" section and the "Run All" button not showing? 64 = Why is the "Summary" section and the "Run All" button not showing? = 65 65 66 66 The cron job did not run, which can be due to: … … 78 78 79 79 == Changelog == 80 81 = 1.14 = 82 83 * Uses the status endpoint to get account data 84 * Fixes the account status not being updated unless a scan is performed when the API token is updated/set 85 * Adds vulnerability found hook 86 * New security check: Check for weak user passwords 87 * New security check: HTTPS 88 * Clear plan info if API Token set to null 89 * Fixes automated scanning when plugin deactivated and reactivated 90 * Fixes cron job not being created when using the WPSCAN_API_TOKEN constant 91 * Change default scanning time to the current time 92 * Many other small improvements 80 93 81 94 = 1.13.2 = -
wpscan/trunk/security-checks/xmlrpc-enabled/check.php
r2433081 r2452411 76 76 } else { 77 77 if ( preg_match( '/<string>Incorrect username or password.<\/string>/', $authenticated_response['body'] ) ) { 78 $this->add_vulnerability( __( 'The XML-RPC interface is enabled. This significantly increases your site\'s attack surface .', 'wpscan' ), 'medium', sanitize_title( $url ) );78 $this->add_vulnerability( __( 'The XML-RPC interface is enabled. This significantly increases your site\'s attack surface', 'wpscan' ), 'medium', sanitize_title( $url ) ); 79 79 return; 80 80 } else { … … 84 84 85 85 if ( preg_match( '/<string>Hello!<\/string>/', $unauthenticated_response['body'] ) ) { 86 $this->add_vulnerability( __( 'The XML-RPC interface is partly disabled, but still allows unauthenticated requests .', 'wpscan' ), 'low', sanitize_title( $url ) );86 $this->add_vulnerability( __( 'The XML-RPC interface is partly disabled, but still allows unauthenticated requests', 'wpscan' ), 'low', sanitize_title( $url ) ); 87 87 } 88 88 } -
wpscan/trunk/views/report.php
r2429586 r2452411 8 8 9 9 <div class="wrap"> 10 <?php echo file_get_contents($this->parent->plugin_dir. 'assets/svg/logo.svg'); ?> 10 <h1> 11 <?php echo file_get_contents($this->parent->plugin_dir. 'assets/svg/logo.svg'); ?> 12 </h1> 11 13 12 14 <hr class="wp-header-end"> … … 41 43 <tr> 42 44 <td scope="col" class="manage-column check-column"> </td> 43 <th scope="col" class="manage-column column-name column-primary" width="250"><?php _e( 'Name', 'wpscan' ) ?></th>45 <th scope="col" class="manage-column column-name column-primary"><?php _e( 'Name', 'wpscan' ) ?></th> 44 46 <th scope="col" class="manage-column column-description"><?php _e( 'Vulnerabilities', 'wpscan' ) ?></th> 45 47 </tr> … … 76 78 <tr> 77 79 <td scope="col" class="manage-column check-column"> </td> 78 <th scope="col" class="manage-column column-name column-primary" width="250"><?php _e( 'Name', 'wpscan' ) ?></th>80 <th scope="col" class="manage-column column-name column-primary"><?php _e( 'Name', 'wpscan' ) ?></th> 79 81 <th scope="col" class="manage-column column-description"><?php _e( 'Vulnerabilities', 'wpscan' ) ?></th> 80 82 </tr> … … 83 85 <?php 84 86 foreach ( get_plugins() as $name => $details ) { 85 $slug = $this->parent->get_plugin_slug( $name, $details );87 $slug = $this->parent->get_plugin_slug( $name, $details ); 86 88 $is_closed = $this->is_item_closed('plugins', $slug); 87 89 ?> … … 124 126 <tr> 125 127 <td scope="col" class="manage-column check-column"> </td> 126 <th scope="col" class="manage-column column-name column-primary" width="250"><?php _e( 'Name', 'wpscan' ) ?></th>128 <th scope="col" class="manage-column column-name column-primary"><?php _e( 'Name', 'wpscan' ) ?></th> 127 129 <th scope="col" class="manage-column column-description"><?php _e( 'Vulnerabilities', 'wpscan' ) ?></th> 128 130 </tr> … … 168 170 <tr> 169 171 <td scope="col" class="manage-column check-column"></td> 170 <th scope="col" class="manage-column column-name column-primary" width="250"><?php _e('Name', 'wpscan') ?></th>172 <th scope="col" class="manage-column column-name column-primary"><?php _e('Name', 'wpscan') ?></th> 171 173 <th scope="col" class="manage-column column-description"><?php _e('Result', 'wpscan') ?></th> 172 174 <th scope="col" class="manage-column column-description"><?php _e('Actions', 'wpscan') ?></th> -
wpscan/trunk/wpscan.php
r2433081 r2452411 4 4 * Plugin URI: http://wordpress.org/plugins/wpscan/ 5 5 * Description: WPScan WordPress Security Scanner. Scans your system for security vulnerabilities listed in the WPScan Vulnerability Database. 6 * Version: 1.1 3.26 * Version: 1.14 7 7 * Author: WPScan Team 8 8 * Author URI: https://wpscan.com/
Note: See TracChangeset
for help on using the changeset viewer.