updated plugin WPScan
version 1.15.4
This commit is contained in:
@ -24,6 +24,7 @@ class System {
|
||||
|
||||
// Current running events.
|
||||
public $current_running = '';
|
||||
|
||||
/**
|
||||
* A list of registered checks.
|
||||
*
|
||||
@ -158,51 +159,12 @@ class System {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List vulnerabilities in the report.
|
||||
*
|
||||
* @param object $check - The check instance.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
* @since 1.0.0
|
||||
*
|
||||
*/
|
||||
public function list_check_vulnerabilities( $instance ) {
|
||||
$vulnerabilities = $instance->get_vulnerabilities();
|
||||
$count = $instance->get_vulnerabilities_count();
|
||||
$ignored = $this->parent->get_ignored_vulnerabilities();
|
||||
|
||||
$not_checked_text = __( 'Not checked yet. Click the Run button to run a scan', 'wpscan' );
|
||||
|
||||
if ( ! isset( $vulnerabilities ) ) {
|
||||
echo esc_html( $not_checked_text );
|
||||
} elseif ( empty( $vulnerabilities ) || 0 === $count ) {
|
||||
echo esc_html( $instance->success_message() );
|
||||
} else {
|
||||
$list = array();
|
||||
|
||||
foreach ( $vulnerabilities as $item ) {
|
||||
if ( in_array( $item['id'], $ignored, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$html = "<div class='vulnerability'>";
|
||||
$html .= "<span class='vulnerability-severity'>";
|
||||
$html .= "<span class='wpscan-" . esc_attr( $item['severity'] ) . "'>" . esc_html( $item['severity'] ) ."</span>";
|
||||
$html .= '</span>';
|
||||
$html .= "<div class='vulnerability-title'>" . wp_kses( $item['title'], array( 'a' => array( 'href' => array() ) ) ) . '</div>';
|
||||
$html .= "<div class='vulnerability-remediation'> <a href='" . $item['remediation_url'] . "' target='_blank'>Click here for further info</a></div>";
|
||||
$html .= '</div>';
|
||||
$list[] = $html;
|
||||
}
|
||||
|
||||
echo join( '<br>', $list );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return vulnerabilities in the report.
|
||||
*
|
||||
* This is very similar, but subtly different to
|
||||
* Report->list_security_check_vulnerabilities().
|
||||
* Should see if they could be merged.
|
||||
*
|
||||
* @param object $check - The check instance.
|
||||
*
|
||||
|
@ -14,10 +14,11 @@ defined( 'ABSPATH' ) || exit;
|
||||
*/
|
||||
class Plugin {
|
||||
// Settings.
|
||||
public $OPT_API_TOKEN = 'wpscan_api_token';
|
||||
public $OPT_API_TOKEN = 'wpscan_api_token';
|
||||
public $OPT_SCANNING_INTERVAL = 'wpscan_scanning_interval';
|
||||
public $OPT_SCANNING_TIME = 'wpscan_scanning_time';
|
||||
public $OPT_IGNORE_ITEMS = 'wpscan_ignore_items';
|
||||
public $OPT_SCANNING_TIME = 'wpscan_scanning_time';
|
||||
public $OPT_IGNORE_ITEMS = 'wpscan_ignore_items';
|
||||
public $OPT_DISABLE_CHECKS = 'wpscan_disable_security_checks';
|
||||
|
||||
// Account.
|
||||
public $OPT_ACCOUNT_STATUS = 'wpscan_account_status';
|
||||
@ -52,9 +53,6 @@ class Plugin {
|
||||
// Plugin path.
|
||||
public $plugin_dir = '';
|
||||
|
||||
// Plugin URI.
|
||||
public $plugin_url = '';
|
||||
|
||||
// Page.
|
||||
public $page_hook = 'toplevel_page_wpscan';
|
||||
|
||||
@ -73,7 +71,6 @@ class Plugin {
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->plugin_dir = trailingslashit( str_replace( '\\', '/', dirname( WPSCAN_PLUGIN_FILE ) ) );
|
||||
$this->plugin_url = site_url( str_replace( str_replace( '\\', '/', ABSPATH ), '', $this->plugin_dir ) );
|
||||
|
||||
// Languages.
|
||||
load_plugin_textdomain( 'wpscan', false, $this->plugin_dir . 'languages' );
|
||||
@ -387,7 +384,7 @@ class Plugin {
|
||||
$this->WPSCAN_ROLE,
|
||||
'wpscan',
|
||||
array( $this->classes['report'], 'page' ),
|
||||
$this->plugin_url . 'assets/svg/menu-icon.svg',
|
||||
plugin_dir_url( dirname( __FILE__ ) ) . 'assets/svg/menu-icon.svg',
|
||||
null
|
||||
);
|
||||
}
|
||||
@ -554,18 +551,20 @@ class Plugin {
|
||||
}
|
||||
|
||||
// Security checks.
|
||||
$this->report['security-checks'] = array();
|
||||
if ( get_option( $this->OPT_DISABLE_CHECKS, array() ) !== '1' ) {
|
||||
$this->report['security-checks'] = array();
|
||||
|
||||
foreach ( $this->classes['checks/system']->checks as $id => $data ) {
|
||||
$data['instance']->perform();
|
||||
$this->report['security-checks'][ $id ]['vulnerabilities'] = array();
|
||||
foreach ( $this->classes['checks/system']->checks as $id => $data ) {
|
||||
$data['instance']->perform();
|
||||
$this->report['security-checks'][ $id ]['vulnerabilities'] = array();
|
||||
|
||||
if ( $data['instance']->vulnerabilities ) {
|
||||
$this->report['security-checks'][ $id ]['vulnerabilities'] = $data['instance']->get_vulnerabilities();
|
||||
if ( $data['instance']->vulnerabilities ) {
|
||||
$this->report['security-checks'][ $id ]['vulnerabilities'] = $data['instance']->get_vulnerabilities();
|
||||
|
||||
$this->maybe_fire_issue_found_action( 'security-check', $id, $this->report['security-checks'][ $id ] );
|
||||
$this->maybe_fire_issue_found_action( 'security-check', $id, $this->report['security-checks'][ $id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Caching.
|
||||
$this->report['cache'] = strtotime( current_time( 'mysql' ) );
|
||||
|
@ -63,6 +63,37 @@ class Report
|
||||
include $this->parent->plugin_dir . '/views/report.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vulnerability status based on fixed_in
|
||||
*
|
||||
* @since 1.15.2
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function status( $vulnerability ) {
|
||||
return empty( $vulnerability->fixed_in )
|
||||
? __( 'We are not aware of a fix for this vulnerability.', 'wpscan' )
|
||||
: sprintf( __( 'This vulnerability was fixed in version %s. We recommend that you update as soon as possible.', 'wpscan' ), esc_html( $vulnerability->fixed_in ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML markup for the vulnerability details
|
||||
*
|
||||
* @since 1.15.2
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function vulnerability_output( $vulnerability ) {
|
||||
$html = '<div class="vulnerability">';
|
||||
$html .= '<p class="vulnerability-title"><b>' . esc_html( $vulnerability->title ) . '</b></p>';
|
||||
$html .= '<p class="vulnerability-status">' . $this->status( $vulnerability ) . '</p>';
|
||||
$html .= $this->vulnerability_severity( $vulnerability );
|
||||
$html .= '<br /><p class="vulnerability-link"><a href="' . esc_url( 'https://wpscan.com/vulnerability/' . $vulnerability->id ) . '" target="_blank">Click here for further details</a></p>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* List vulnerabilities on screen
|
||||
*
|
||||
@ -99,21 +130,14 @@ class Report
|
||||
|
||||
usort( $report['vulnerabilities'], array( 'self', 'sort_vulnerabilities' ) );
|
||||
|
||||
foreach ( $report['vulnerabilities'] as $item ) {
|
||||
$id = 'security-checks' === $type ? $item['id'] : $item->id;
|
||||
foreach ( $report['vulnerabilities'] as $vulnerability ) {
|
||||
$id = 'security-checks' === $type ? $vulnerability['id'] : $vulnerability->id;
|
||||
|
||||
if ( in_array( $id, $ignored, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$html = '<div class="vulnerability">';
|
||||
$html .= $this->vulnerability_severity( $item );
|
||||
$html .= '<a href="' . esc_url( 'https://wpscan.com/vulnerability/' . $item->id ) . '" target="_blank">';
|
||||
$html .= $this->parent->get_sanitized_vulnerability_title( $item );
|
||||
$html .= '</a>';
|
||||
$html .= '</div>';
|
||||
|
||||
$list[] = $html;
|
||||
$list[] = $this->vulnerability_output( $vulnerability );
|
||||
}
|
||||
|
||||
echo empty( $list ) ? $null_text : join( '<br>', $list );
|
||||
@ -123,6 +147,53 @@ class Report
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List security check vulnerabilities in the report.
|
||||
* This should be merged with the list_api_vulnerabilities() function,
|
||||
* in the future, if anyone can figure out how...
|
||||
*
|
||||
* @param object $check - The check instance.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
* @since 1.0.0
|
||||
*
|
||||
*/
|
||||
public function list_security_check_vulnerabilities( $instance ) {
|
||||
$vulnerabilities = $instance->get_vulnerabilities();
|
||||
$count = $instance->get_vulnerabilities_count();
|
||||
$ignored = $this->parent->get_ignored_vulnerabilities();
|
||||
|
||||
$not_checked_text = __( 'Not checked yet. Click the Run button to run a scan', 'wpscan' );
|
||||
|
||||
if ( ! isset( $vulnerabilities ) ) {
|
||||
echo esc_html( $not_checked_text );
|
||||
} elseif ( empty( $vulnerabilities ) || 0 === $count ) {
|
||||
echo esc_html( $instance->success_message() );
|
||||
} else {
|
||||
$list = array();
|
||||
|
||||
foreach ( $vulnerabilities as $vulnerability ) {
|
||||
if ( in_array( $vulnerability['id'], $ignored, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$html = "<div class='vulnerability'>";
|
||||
$html .= "<p class='vulnerability-title'>" . wp_kses( $vulnerability['title'], array( 'a' => array( 'href' => array() ) ) ) . '</p><br />';
|
||||
$html .= "<p class='vulnerability-severity'>";
|
||||
$html .= "<span class='wpscan-" . esc_attr( $vulnerability['severity'] ) . "'>" . esc_html( $vulnerability['severity'] ) ." Severity</span>";
|
||||
$html .= '</p>';
|
||||
$html .= "<br /><br /><p class='vulnerability-link'><a href='" . esc_url( $vulnerability['remediation_url'] ) . "' target='_blank'>Click here for further details</a></p>";
|
||||
$html .= '</div>';
|
||||
|
||||
$list[] = $html;
|
||||
}
|
||||
|
||||
echo join( '<br>', $list );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sort vulnerabilities by severity
|
||||
*
|
||||
@ -155,7 +226,7 @@ class Report
|
||||
|
||||
if ( isset( $vulnerability->cvss->severity ) ) {
|
||||
$severity = $vulnerability->cvss->severity;
|
||||
$html .= "<span class='wpscan-" . esc_attr( $severity ) . "'>" . esc_html( $severity ) . '</span>';
|
||||
$html .= "<span class='wpscan-" . esc_attr( $severity ) . "'>" . esc_html( $severity ) . ' Severity</span>';
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
|
@ -82,6 +82,7 @@ class Settings {
|
||||
register_setting( $this->page, $this->parent->OPT_IGNORE_ITEMS );
|
||||
register_setting( $this->page, $this->parent->OPT_SCANNING_INTERVAL, 'sanitize_text_field' );
|
||||
register_setting( $this->page, $this->parent->OPT_SCANNING_TIME, 'sanitize_text_field' );
|
||||
register_setting( $this->page, $this->parent->OPT_DISABLE_CHECKS, array( 'type' => 'boolean', 'default' => '0' ) );
|
||||
|
||||
$section = $this->page . '_section';
|
||||
|
||||
@ -116,6 +117,14 @@ class Settings {
|
||||
$section
|
||||
);
|
||||
|
||||
add_settings_field(
|
||||
$this->parent->OPT_DISABLE_CHECKS,
|
||||
__( 'Disable Security Checks', 'wpscan' ),
|
||||
array( $this, 'field_disable_security_checks' ),
|
||||
$this->page,
|
||||
$section
|
||||
);
|
||||
|
||||
add_settings_field(
|
||||
$this->parent->OPT_IGNORE_ITEMS,
|
||||
__( 'Ignore Items', 'wpscan' ),
|
||||
@ -197,7 +206,7 @@ class Settings {
|
||||
*/
|
||||
public function page() {
|
||||
echo '<div class="wrap">';
|
||||
echo '<h1><img src="' . $this->parent->plugin_url . 'assets/svg/logo.svg" alt="WPScan"></h1>';
|
||||
echo '<h1><img src="' . plugin_dir_url( dirname( __FILE__ ) ) . 'assets/svg/logo.svg" alt="WPScan"></h1>';
|
||||
|
||||
echo '<h2>' . __( 'Settings', 'wpscan' ) . '</h2>';
|
||||
|
||||
@ -323,6 +332,21 @@ class Settings {
|
||||
|
||||
echo '</p><br/>';
|
||||
}
|
||||
/**
|
||||
* Disable security checks field
|
||||
*
|
||||
* @since 1.15.2
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function field_disable_security_checks() {
|
||||
$opt = $this->parent->OPT_DISABLE_CHECKS;
|
||||
|
||||
$value = get_option( $opt, array() );
|
||||
$checked = $value === '1' ? 'checked' : null;
|
||||
|
||||
echo "<input name='{$opt}' type='checkbox' $checked value='1' >";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore items field
|
||||
|
@ -25,7 +25,11 @@ class Summary {
|
||||
|
||||
add_action( 'admin_init', array( $this, 'add_meta_box_summary' ) );
|
||||
add_action( 'wp_ajax_wpscan_check_now', array( $this, 'ajax_check_now' ) );
|
||||
add_action( 'wp_ajax_wpscan_security_check_now', array( $this, 'ajax_security_check_now' ) );
|
||||
|
||||
if ( get_option( $this->parent->OPT_DISABLE_CHECKS, array() ) !== '1' ) {
|
||||
add_action( 'wp_ajax_wpscan_security_check_now', array( $this, 'ajax_security_check_now' ) );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_' . $this->parent->WPSCAN_TRANSIENT_CRON, array( $this, 'ajax_doing_cron' ) );
|
||||
}
|
||||
|
||||
@ -161,7 +165,7 @@ class Summary {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax scurity check now
|
||||
* Ajax security check now
|
||||
*
|
||||
* @return void
|
||||
* @since 1.0.0
|
||||
|
@ -127,9 +127,11 @@ class ignoreVulnerabilities {
|
||||
foreach ( wp_get_themes() as $name => $details ) {
|
||||
$this->list_vulnerabilities_to_ignore( 'themes', $this->parent->get_theme_slug( $name, $details ) );
|
||||
}
|
||||
|
||||
foreach ( $this->parent->classes['checks/system']->checks as $id => $data ) {
|
||||
$this->list_vulnerabilities_to_ignore( 'security-checks', $id );
|
||||
|
||||
if ( get_option( $this->parent->OPT_DISABLE_CHECKS, array() ) !== '1' ) {
|
||||
foreach ( $this->parent->classes['checks/system']->checks as $id => $data ) {
|
||||
$this->list_vulnerabilities_to_ignore( 'security-checks', $id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user