Last active
August 29, 2015 14:23
-
-
Save marcus-downing/30f1fbb6272e1dc839f0 to your computer and use it in GitHub Desktop.
Plugin Security Scanner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Plugin Security Scanner | |
* Plugin URI: http://www.glenscott.co.uk/plugin-security-scanner/ | |
* Description: This plugin determines whether any of your plugins have security vulnerabilities. It does this by looking up details in the WPScan Vulnerability Database. | |
* Version: 1.1.9 | |
* Author: Glen Scott | |
* Author URI: http://www.glenscott.co.uk | |
* License: GPL2 | |
*/ | |
/* Copyright 2015 Glen Scott (email : [email protected]) | |
This program is free software; you can redistribute it and/or modify | |
it under the terms of the GNU General Public License, version 2, as | |
published by the Free Software Foundation. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with this program; if not, write to the Free Software | |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
*/ | |
defined( 'ABSPATH' ) or die( 'No script kiddies please!' ); | |
if ( ! class_exists( 'WP_Http' ) ) { | |
include_once( ABSPATH . WPINC. '/class-http.php' ); | |
} | |
// Check if get_plugins() function exists. This is required on the front end of the | |
// site, since it is in a file that is normally only loaded in the admin. | |
if ( ! function_exists( 'get_plugins' ) ) { | |
require_once ABSPATH . 'wp-admin/includes/plugin.php'; | |
} | |
/** Step 2 (from text above). */ | |
add_action( 'admin_menu', 'plugin_security_scanner_menu' ); | |
/** Step 1. */ | |
function plugin_security_scanner_menu() { | |
add_management_page( | |
__('Plugin Security Scanner', 'plugin_security_scanner'), | |
__('Plugin Security Scanner', 'plugin_security_scanner'), | |
'manage_options', 'plugin-security-scanner', 'plugin_security_scanner_options' ); | |
} | |
function plugin_security_scanner_get_vulnerabilities($schedule) { | |
$request = new WP_Http; | |
$vulnerabilities = array(); | |
foreach ( get_plugins() as $name => $details ) { | |
// get unique name | |
if ( preg_match( '|(.+)/|', $name, $matches ) ) { | |
$result = $request->request( 'https://wpvulndb.com/api/v1/plugins/' . $matches[1] ); | |
if ( $result['body'] ) { | |
$plugin = json_decode( $result['body'] ); | |
if ( isset( $plugin->plugin->vulnerabilities ) ) { | |
foreach ( $plugin->plugin->vulnerabilities as $vuln ) { | |
if ( !isset($vuln->fixed_in) || | |
version_compare( $details['Version'], $vuln->fixed_in, '<' ) ) { | |
$vulnerabilities[$name][] = $vuln; | |
} | |
} | |
} | |
} | |
} | |
} | |
do_action('plugin_security_scanner_vulnerabilities', $vulnerabilities, $schedule); | |
return $vulnerabilities; | |
} | |
/** Step 3. */ | |
function plugin_security_scanner_options() { | |
if ( ! current_user_can( 'manage_options' ) ) { | |
wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); | |
} | |
echo '<div class="wrap">'; | |
echo '<h2>' . __('Plugin Security Scanner', 'plugin_security_scanner') . '</h2>'; | |
flush(); | |
$vulnerabilities = plugin_security_scanner_get_vulnerabilities('options'); | |
if (!empty($vulnerabilities)) { | |
$plugins = get_plugins(); | |
$vulnerability_count = 0; | |
foreach ($vulnerabilities as $name => $plugin_vulnerabilities) { | |
$plugin = $plugins[$name]; | |
echo "<h3>".__($plugin['Name'])."</h3>\n"; | |
foreach ($plugin_vulnerabilities as $vuln) { | |
echo '<p><strong>' . | |
__('Vulnerability found', 'plugin_security_scanner') . | |
':</strong> ' . esc_html( $vuln->title ) . | |
' -- <a href="' . esc_url( 'https://wpvulndb.com/vulnerabilities/' . $vuln->id ) . | |
'" target="_blank">' . __('View details', 'plugin_security_scanner') . '</a></p>'; | |
$vulnerability_count++; | |
} | |
} | |
echo '<p>' . sprintf( _n( | |
'Scan completed: %s vulnerability found.', | |
'Scan completed: %s vulnerabilities found.', | |
$vulnerability_count, 'plugin_security_scanner'), '<strong>'.$vulnerability_count.'</strong>' ) . | |
'</p>'; | |
} else { | |
echo '<p>'.__('No vulnerabilities found', 'plugin_security_scanner').'</p>'; | |
} | |
echo '</div>'; | |
} | |
// scheduled email to admin | |
register_activation_hook( __FILE__, 'plugin_security_scanner_activation' ); | |
/** | |
* On activation, set a time, frequency and name of an action hook to be scheduled. | |
*/ | |
function plugin_security_scanner_activation() { | |
wp_schedule_event( time(), 'daily', 'plugin_security_scanner_daily_event_hook' ); | |
} | |
add_action( 'plugin_security_scanner_daily_event_hook', 'plugin_security_scanner_do_this_daily' ); | |
add_action( 'plugin_security_scanner_vulnerabilities', 'plugin_security_scanner_daily_email', 2 ); | |
/** | |
* On the scheduled action hook, run the function. | |
*/ | |
function plugin_security_scanner_do_this_daily() { | |
plugin_security_scanner_get_vulnerabilities('daily'); | |
} | |
/** | |
* Default action: send an email to the site admin | |
*/ | |
function plugin_security_scanner_daily_email($vulnerabilities, $schedule) { | |
$admin_email = get_option( 'admin_email' ); | |
if ( $admin_email && $schedule == 'daily' && !empty($vulnerabilities)) { | |
$mail_body = ''; | |
foreach ($vulnerabilities as $name => $plugin_vulnerabilities) { | |
foreach ($plugin_vulnerabilities as $vuln) { | |
$mail_body .= 'Vulnerability found: ' . $vuln->title . "\n"; | |
} | |
} | |
// if vulns, email admin | |
$msg = sprintf(_n( | |
'Scan completed: %s vulnerability found.', | |
'Scan completed: %s vulnerabilities found.', | |
$vulnerability_count, 'plugin_security_scanner'), $vulnerability_count); | |
$mail_body .= "\n\n" . $msg . "\n"; | |
$date = date_i18n( get_option( 'date_format' ) ); | |
$mail_subject = get_bloginfo() . sprintf(__(' Plugin Security Scan %s', 'plugin_security_scanner'), $date ); | |
wp_mail( $admin_email, $mail_subject, $mail_body ); | |
} | |
} | |
register_deactivation_hook( __FILE__, 'prefix_deactivation' ); | |
/** | |
* On deactivation, remove all functions from the scheduled action hook. | |
*/ | |
function prefix_deactivation() { | |
wp_clear_scheduled_hook( 'plugin_security_scanner_daily_event_hook' ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment