1,225 changes: 1,225 additions & 0 deletions assets/css/jquery-ui-styles/1.11.4/jquery-ui.css

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions assets/css/jquery-ui-styles/1.11.4/jquery-ui.min.css

Large diffs are not rendered by default.

1,311 changes: 1,311 additions & 0 deletions assets/css/jquery-ui-styles/1.12.1/jquery-ui.css

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions assets/css/jquery-ui-styles/1.12.1/jquery-ui.min.css

Large diffs are not rendered by default.

1,314 changes: 1,314 additions & 0 deletions assets/css/jquery-ui-styles/1.13.0/jquery-ui.css

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions assets/css/jquery-ui-styles/1.13.0/jquery-ui.min.css

Large diffs are not rendered by default.

1,314 changes: 1,314 additions & 0 deletions assets/css/jquery-ui-styles/1.13.1/jquery-ui.css

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions assets/css/jquery-ui-styles/1.13.1/jquery-ui.min.css

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions assets/js/scripts-admin-global.js
Expand Up @@ -6,10 +6,11 @@ jQuery(function($) {
*/
$('.wpmm_notices').on('click', '.notice-dismiss', function() {
var notice_key = $(this).parent().data('key');

var notice_nonce = $(this).parent().data('nonce');
$.post(ajaxurl, {
action: 'wpmm_dismiss_notices',
notice_key: notice_key
notice_key: notice_key,
_nonce: notice_nonce
}, function(response) {
if (!response.success) {
// alert(response.data);
Expand Down
9 changes: 7 additions & 2 deletions assets/js/scripts-admin.js
Expand Up @@ -132,7 +132,8 @@ jQuery(function ($) {
* SUBSCRIBERS EXPORT
*/
$('#subscribers_wrap').on('click', '#subscribers-export', function () {
$('<iframe />').attr('src', wpmm_vars.ajax_url + '?action=wpmm_subscribers_export').appendTo('body').hide();
var nonce = $('#tab-modules #_wpnonce').val();
$('<iframe />').attr('src', wpmm_vars.ajax_url + '?action=wpmm_subscribers_export&_wpnonce='+encodeURI( nonce )).appendTo('body').hide();
});

/**
Expand All @@ -141,8 +142,12 @@ jQuery(function ($) {
* @since 2.0.4
*/
$('#subscribers_wrap').on('click', '#subscribers-empty-list', function () {

var nonce = $('#tab-modules #_wpnonce').val();

$.post(wpmm_vars.ajax_url, {
action: 'wpmm_subscribers_empty_list'
action: 'wpmm_subscribers_empty_list',
_wpnonce: nonce
}, function (response) {
if (!response.success) {
alert(response.data);
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -2,7 +2,7 @@
"name": "codeinwp/wp-maintenance-mode",
"description": "Adds a splash page to your site that lets visitors know your site is down for maintenance. Full access to the back- & front-end is optional.",
"type": "wordpress-plugin",
"version": "2.4.4",
"version": "2.4.5",
"license": "GPL-2.0+",
"homepage": "https://themeisle.com",
"support": {
Expand Down
72 changes: 54 additions & 18 deletions includes/classes/wp-maintenance-mode-admin.php
Expand Up @@ -81,10 +81,15 @@ public function enqueue_admin_styles() {

$screen = get_current_screen();
if ( $this->plugin_screen_hook_suffix === $screen->id ) {
$wp_scripts = wp_scripts();
$ui = $wp_scripts->query( 'jquery-ui-core' );

wp_enqueue_style( $this->plugin_slug . '-admin-jquery-ui-styles', '//code.jquery.com/ui/' . ( ! empty( $ui->ver ) ? $ui->ver : '1.11.4' ) . '/themes/smoothness/jquery-ui' . WPMM_ASSETS_SUFFIX . '.css', array(), WP_Maintenance_Mode::VERSION );
$wp_scripts = wp_scripts();
$ui = $wp_scripts->query( 'jquery-ui-core' );
$allowed_versions = array(
'1.11.4' => true,
'1.12.1' => true,
'1.13.0' => true,
'1.13.1' => true,
);
wp_enqueue_style( $this->plugin_slug . '-admin-jquery-ui-styles', WPMM_CSS_URL . 'jquery-ui-styles/' . ( ! empty( $ui->ver ) ? ( isset( $allowed_versions[ $ui->ver ] ) ? $ui->ver : '1.13.1' ) : '1.11.4' ) . '/jquery-ui' . WPMM_ASSETS_SUFFIX . '.css', array(), WP_Maintenance_Mode::VERSION );
wp_enqueue_style( $this->plugin_slug . '-admin-chosen', WPMM_CSS_URL . 'chosen' . WPMM_ASSETS_SUFFIX . '.css', array(), WP_Maintenance_Mode::VERSION );
wp_enqueue_style( $this->plugin_slug . '-admin-timepicker-addon-script', WPMM_CSS_URL . 'jquery-ui-timepicker-addon' . WPMM_ASSETS_SUFFIX . '.css', array(), WP_Maintenance_Mode::VERSION );
wp_enqueue_style( $this->plugin_slug . '-admin-styles', WPMM_CSS_URL . 'style-admin' . WPMM_ASSETS_SUFFIX . '.css', array( 'wp-color-picker' ), WP_Maintenance_Mode::VERSION );
Expand Down Expand Up @@ -156,7 +161,15 @@ public function subscribers_export() {
if ( ! current_user_can( wpmm_get_capability( 'subscribers' ) ) ) {
throw new Exception( __( 'You do not have access to this resource.', 'wp-maintenance-mode' ) );
}
// check nonce existence
if ( empty( $_GET['_wpnonce'] ) ) {
throw new Exception( __( 'The nonce field must not be empty.', 'wp-maintenance-mode' ) );
}

// check nonce validation
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'tab-modules' ) ) {
throw new Exception( __( 'Security check.', 'wp-maintenance-mode' ) );
}
// get subscribers and export
$results = $wpdb->get_results( "SELECT email, insert_date FROM {$wpdb->prefix}wpmm_subscribers ORDER BY id_subscriber DESC", ARRAY_A );
if ( ! empty( $results ) ) {
Expand All @@ -174,6 +187,7 @@ public function subscribers_export() {

fclose( $fp ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
}
die();
} catch ( Exception $ex ) {
wp_send_json_error( $ex->getMessage() );
}
Expand All @@ -194,7 +208,15 @@ public function subscribers_empty_list() {
if ( ! current_user_can( wpmm_get_capability( 'subscribers' ) ) ) {
throw new Exception( __( 'You do not have access to this resource.', 'wp-maintenance-mode' ) );
}
// check nonce existence
if ( empty( $_POST['_wpnonce'] ) ) {
throw new Exception( __( 'The nonce field must not be empty.', 'wp-maintenance-mode' ) );
}

// check nonce validation
if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'tab-modules' ) ) {
throw new Exception( __( 'Security check.', 'wp-maintenance-mode' ) );
}
// delete all subscribers
$wpdb->query( "DELETE FROM {$wpdb->prefix}wpmm_subscribers" );

Expand Down Expand Up @@ -258,7 +280,7 @@ public function save_plugin_settings() {
}

// check existence in plugin default settings
$tab = $_POST['tab'];
$tab = sanitize_key( $_POST['tab'] );
if ( empty( $this->plugin_default_settings[ $tab ] ) ) {
die( esc_html__( 'The tab slug must exist.', 'wp-maintenance-mode' ) );
}
Expand All @@ -270,15 +292,18 @@ public function save_plugin_settings() {
if ( ! empty( $_POST['options']['general']['status'] ) && $_POST['options']['general']['status'] === 1 ) {
$_POST['options']['general']['status_date'] = date( 'Y-m-d H:i:s' );
}
$_POST['options']['general']['bypass_bots'] = (int) $_POST['options']['general']['bypass_bots'];
$_POST['options']['general']['backend_role'] = ! empty( $_POST['options']['general']['backend_role'] ) ? $_POST['options']['general']['backend_role'] : array();
$_POST['options']['general']['frontend_role'] = ! empty( $_POST['options']['general']['frontend_role'] ) ? $_POST['options']['general']['frontend_role'] : array();
$_POST['options']['general']['meta_robots'] = (int) $_POST['options']['general']['meta_robots'];
$_POST['options']['general']['redirection'] = esc_url_raw( $_POST['options']['general']['redirection'] );
$_POST['options']['general']['bypass_bots'] = (int) $_POST['options']['general']['bypass_bots'];

$_POST['options']['general']['backend_role'] = ! empty( $_POST['options']['general']['backend_role'] ) ? array_map( 'sanitize_text_field', $_POST['options']['general']['backend_role'] ) : array();
$_POST['options']['general']['frontend_role'] = ! empty( $_POST['options']['general']['frontend_role'] ) ? array_map( 'sanitize_text_field', $_POST['options']['general']['frontend_role'] ) : array();

$_POST['options']['general']['meta_robots'] = (int) $_POST['options']['general']['meta_robots'];
$_POST['options']['general']['redirection'] = esc_url_raw( $_POST['options']['general']['redirection'] );
if ( ! empty( $_POST['options']['general']['exclude'] ) ) {
$exclude_array = explode( "\n", $_POST['options']['general']['exclude'] );
// we need to be sure that empty lines will not be saved
$_POST['options']['general']['exclude'] = array_filter( array_map( 'trim', $exclude_array ) );
$_POST['options']['general']['exclude'] = array_map( 'sanitize_textarea_field', $_POST['options']['general']['exclude'] );
} else {
$_POST['options']['general']['exclude'] = array();
}
Expand Down Expand Up @@ -325,13 +350,16 @@ public function save_plugin_settings() {
break;
case 'modules':
// Countdown
$_POST['options']['modules']['countdown_status'] = (int) $_POST['options']['modules']['countdown_status'];
$_POST['options']['modules']['countdown_start'] = sanitize_text_field( $_POST['options']['modules']['countdown_start'] );
$_POST['options']['modules']['countdown_details'] = array_map( 'trim', $_POST['options']['modules']['countdown_details'] );
$_POST['options']['modules']['countdown_details']['days'] = isset( $_POST['options']['modules']['countdown_details']['days'] ) && is_numeric( $_POST['options']['modules']['countdown_details']['days'] ) ? $_POST['options']['modules']['countdown_details']['days'] : 0;
$_POST['options']['modules']['countdown_details']['hours'] = isset( $_POST['options']['modules']['countdown_details']['hours'] ) && is_numeric( $_POST['options']['modules']['countdown_details']['hours'] ) ? $_POST['options']['modules']['countdown_details']['hours'] : 1;
$_POST['options']['modules']['countdown_details']['minutes'] = isset( $_POST['options']['modules']['countdown_details']['minutes'] ) && is_numeric( $_POST['options']['modules']['countdown_details']['minutes'] ) ? $_POST['options']['modules']['countdown_details']['minutes'] : 0;
$_POST['options']['modules']['countdown_color'] = sanitize_hex_color( $_POST['options']['modules']['countdown_color'] );
$_POST['options']['modules']['countdown_status'] = (int) $_POST['options']['modules']['countdown_status'];
$_POST['options']['modules']['countdown_start'] = sanitize_text_field( $_POST['options']['modules']['countdown_start'] );
$_POST['options']['modules']['countdown_details'] = array_map( 'trim', $_POST['options']['modules']['countdown_details'] );
$_POST['options']['modules']['countdown_details'] = array(
'days' => isset( $_POST['options']['modules']['countdown_details']['days'] ) && is_numeric( $_POST['options']['modules']['countdown_details']['days'] ) ? sanitize_text_field( $_POST['options']['modules']['countdown_details']['days'] ) : 0,
'hours' => isset( $_POST['options']['modules']['countdown_details']['hours'] ) && is_numeric( $_POST['options']['modules']['countdown_details']['hours'] ) ? sanitize_text_field( $_POST['options']['modules']['countdown_details']['hours'] ) : 1,
'minutes' => isset( $_POST['options']['modules']['countdown_details']['minutes'] ) && is_numeric( $_POST['options']['modules']['countdown_details']['minutes'] ) ? sanitize_text_field( $_POST['options']['modules']['countdown_details']['minutes'] ) : 0,
);

$_POST['options']['modules']['countdown_color'] = sanitize_hex_color( $_POST['options']['modules']['countdown_color'] );

// Subscribe
$_POST['options']['modules']['subscribe_status'] = (int) $_POST['options']['modules']['subscribe_status'];
Expand Down Expand Up @@ -456,7 +484,7 @@ public function reset_plugin_settings() {
}

// check existence in plugin default settings
$tab = $_POST['tab'];
$tab = sanitize_key( $_POST['tab'] );
if ( empty( $this->plugin_default_settings[ $tab ] ) ) {
throw new Exception( __( 'The tab slug must exist.', 'wp-maintenance-mode' ) );
}
Expand Down Expand Up @@ -626,6 +654,14 @@ public function dismiss_notices() {
if ( empty( $notice_key ) ) {
throw new Exception( __( 'Notice key cannot be empty.', 'wp-maintenance-mode' ) );
}
if ( empty( $_POST['_wpnonce'] ) ) {
throw new Exception( __( 'The nonce field must not be empty.', 'wp-maintenance-mode' ) );
}

// check nonce validation
if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'notice_nonce_' . $notice_key ) ) {
throw new Exception( __( 'Security check.', 'wp-maintenance-mode' ) );
}

$this->save_dismissed_notices( get_current_user_id(), $notice_key );

Expand Down
4 changes: 2 additions & 2 deletions includes/classes/wp-maintenance-mode-shortcodes.php
Expand Up @@ -39,9 +39,9 @@ public static function shortcode_wrapper( $function, $atts = array(), $wrapper =
ob_start();

// @codingStandardsIgnoreStart
echo $wrapper['before'];
echo wp_kses_post( $wrapper['before'] );
call_user_func( $function, $atts );
echo $wrapper['after'];
echo wp_kses_post( $wrapper['after'] );
// @codingStandardsIgnoreEnd

return ob_get_clean();
Expand Down
30 changes: 23 additions & 7 deletions includes/classes/wp-maintenance-mode.php
Expand Up @@ -6,7 +6,7 @@

class WP_Maintenance_Mode {

const VERSION = '2.4.4';
const VERSION = '2.4.5';

protected $plugin_slug = 'wp-maintenance-mode';
protected $plugin_settings;
Expand Down Expand Up @@ -756,6 +756,16 @@ public function check_search_bots() {
return $is_search_bot;
}

/**
* Sanitize IP adress.
*
* @param string $ip Ip string.
*
* @return array|string|string[]|null
*/
public static function sanitize_ip( $ip ) {
return preg_replace( '/[^0-9a-fA-F:., ]/', '', $ip );
}
/**
* Check if slug / ip address exists in exclude list
*
Expand All @@ -769,8 +779,9 @@ public function check_exclude() {
if ( ! empty( $this->plugin_settings['general']['exclude'] ) && is_array( $this->plugin_settings['general']['exclude'] ) ) {
$excluded_list = $this->plugin_settings['general']['exclude'];
$remote_address = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : '';
$remote_address = self::sanitize_ip( $remote_address );
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? rawurldecode( $_SERVER['REQUEST_URI'] ) : '';

$request_uri = wp_sanitize_redirect( $request_uri );
foreach ( $excluded_list as $item ) {
if ( empty( $item ) ) { // just to be sure :-)
continue;
Expand Down Expand Up @@ -943,7 +954,7 @@ public function add_inline_css_style() {
return;
}

printf( "<style type=\"text/css\">\n%s\n</style>\n", implode( "\n", $css_rules ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
printf( "<style type=\"text/css\">\n%s\n</style>\n", wp_strip_all_tags( implode( "\n", $css_rules ) ) );
}

/**
Expand All @@ -952,10 +963,9 @@ public function add_inline_css_style() {
* @since 2.4.0
*/
public function add_js_files() {
$wp_scripts = wp_scripts();

$scripts = array(
'jquery' => ! empty( $wp_scripts->registered['jquery-core'] ) ? site_url( $wp_scripts->registered['jquery-core']->src ) : '//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery' . WPMM_ASSETS_SUFFIX . '.js',
'jquery' => site_url( '/wp-includes/js/jquery/jquery' . WPMM_ASSETS_SUFFIX . '.js' ),
'fitvids' => WPMM_JS_URL . 'jquery.fitvids' . WPMM_ASSETS_SUFFIX . '.js',
'frontend' => WPMM_JS_URL . 'scripts' . WPMM_ASSETS_SUFFIX . '.js?ver=' . self::VERSION,
);
Expand Down Expand Up @@ -1006,7 +1016,10 @@ public function add_subscriber() {
if ( empty( $email ) || ! is_email( $email ) ) {
throw new Exception( __( 'Please enter a valid email address.', 'wp-maintenance-mode' ) );
}

if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'wpmts_nonce_subscribe' )
) {
throw new Exception( __( 'Security check.', 'wp-maintenance-mode' ) );
}
// save
$exists = $wpdb->get_row( $wpdb->prepare( "SELECT id_subscriber FROM {$wpdb->prefix}wpmm_subscribers WHERE email = %s", $email ), ARRAY_A );
if ( empty( $exists ) ) {
Expand Down Expand Up @@ -1041,7 +1054,10 @@ public function send_contact() {
if ( empty( $name ) || empty( $email ) || empty( $content ) ) {
throw new Exception( __( 'All fields required.', 'wp-maintenance-mode' ) );
}

if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'wpmts_nonce_contact' )
) {
throw new Exception( __( 'Security check.', 'wp-maintenance-mode' ) );
}
if ( ! is_email( $email ) ) {
throw new Exception( __( 'Please enter a valid email address.', 'wp-maintenance-mode' ) );
}
Expand Down
4 changes: 2 additions & 2 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "wp-maintenance-mode",
"version": "2.4.4",
"version": "2.4.5",
"author": "Themeisle",
"homepage": "https://themeisle.com/",
"license": "GPL-3.0+",
Expand All @@ -22,7 +22,7 @@
"cssnano": "^4.1.11",
"grunt": "^1.4.0",
"grunt-contrib-jshint": "^2.1.0",
"grunt-contrib-uglify-es": "git://github.com/gruntjs/grunt-contrib-uglify.git#harmony",
"grunt-contrib-uglify-es": "^3.3.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-postcss": "^0.9.0",
"grunt-version": "^3.0.0",
Expand Down
11 changes: 9 additions & 2 deletions readme.txt
Expand Up @@ -6,8 +6,8 @@ Author: Themeisle
Author URI: https://themeisle.com/
Tags: maintenance mode, admin, administration, unavailable, coming soon, multisite, landing page, under construction, contact form, subscribe, countdown
Requires at least: 3.5
Tested up to: 5.9
Stable tag: trunk
Tested up to: 6.0
Stable tag: 2.4.5
Requires PHP: 5.6
License: GPL-2.0+

Expand Down Expand Up @@ -91,6 +91,13 @@ Notice: `wp-cron.php` is excluded by default.

== Changelog ==

##### [Version 2.4.5](https://github.com/Codeinwp/wp-maintenance-mode/compare/v2.4.4...v2.4.5) (2022-06-15)

* Harden security and improve release process




##### [Version 2.4.4](https://github.com/Codeinwp/wp-maintenance-mode/compare/v2.4.3...v2.4.4) (2022-02-10)

Update dependencies
Expand Down
5 changes: 3 additions & 2 deletions views/maintenance.php
Expand Up @@ -49,7 +49,7 @@
if ( ! empty( $text ) && $this->plugin_settings['bot']['status'] === 0 ) {
?>
<!-- Text -->
<h2><?php echo $text; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></h2>
<h2><?php echo wp_kses_post( $text ); ?></h2>
<?php
}
?>
Expand Down Expand Up @@ -97,6 +97,7 @@
<form class="subscribe_form">
<div class="subscribe_border">
<input type="text" placeholder="<?php esc_attr_e( 'your e-mail...', 'wp-maintenance-mode' ); ?>" name="email" class="email_input" data-rule-required="true" data-rule-email="true" data-rule-required="true" data-rule-email="true" />
<?php wp_nonce_field( 'wpmts_nonce_subscribe' ); ?>
<input type="submit" value="<?php esc_attr_e( 'Subscribe', 'wp-maintenance-mode' ); ?>" />
</div>
<?php if ( ! empty( $this->plugin_settings['gdpr']['status'] ) && $this->plugin_settings['gdpr']['status'] === 1 ) { ?>
Expand Down Expand Up @@ -171,7 +172,7 @@
<p class="col last">
<input type="text" placeholder="<?php esc_attr_e( 'E-mail', 'wp-maintenance-mode' ); ?>" data-rule-required="true" data-rule-email="true" data-msg-required="<?php esc_attr_e( 'This field is required.', 'wp-maintenance-mode' ); ?>" data-msg-email="<?php esc_attr_e( 'Please enter a valid email address.', 'wp-maintenance-mode' ); ?>" name="email" class="email_input" />
</p>

<?php wp_nonce_field( 'wpmts_nonce_contact' ); ?>
<br clear="all" />

<?php do_action( 'wpmm_contact_form_before_message' ); ?>
Expand Down
2 changes: 1 addition & 1 deletion views/notices.php
Expand Up @@ -12,5 +12,5 @@
continue;
}

printf( '<div id="message" class="%s" data-key="%s"><p>%s</p></div>', esc_attr( $notice['class'] ), esc_attr( $key ), wp_kses_post( $notice['msg'] ) );
printf( '<div id="message" class="%s" data-key="%s" data-nonce="%s"><p>%s</p></div>', esc_attr( $notice['class'] ), esc_attr( $key ), esc_attr( wp_create_nonce( 'notice_nonce_' . $key ) ), wp_kses_post( $notice['msg'] ) );
}
2 changes: 1 addition & 1 deletion wp-maintenance-mode.php
Expand Up @@ -4,7 +4,7 @@
*
* Plugin Name: WP Maintenance Mode & Coming Soon
* Description: Adds a splash page to your site that lets visitors know your site is down for maintenance. It's perfect for a coming soon page.
* Version: 2.4.4
* Version: 2.4.5
* Author: Themeisle
* Author URI: https://themeisle.com/
* Twitter: themeisle
Expand Down
922 changes: 626 additions & 296 deletions yarn.lock

Large diffs are not rendered by default.