Skip to content

Commit

Permalink
Add nonce validation in admin pages (#22)
Browse files Browse the repository at this point in the history
Fix a Cross-Site Request Forgery issue due to nonce validation not being implemented.
  • Loading branch information
fernandomm authored Oct 24, 2023
1 parent 3969b80 commit fa562b5
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 15 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Security
- Added nonce validation in admin pages

## [2.1.1] - 2022-09-15

### Fixed
Expand Down
49 changes: 37 additions & 12 deletions inc/class-mailrelaypages.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,18 @@ public function render_admin_page() {

load_plugin_textdomain( 'mailrelay', false, 'mailrelay/languages/' );

if ( isset( $_POST['action'] ) ) {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
if ( isset($_SERVER['REQUEST_METHOD']) && 'POST' === $_SERVER['REQUEST_METHOD'] && ! wp_verify_nonce(sanitize_key($_POST['_mailrelay_nonce']), '_mailrelay_nonce') ) {
wp_die(
'Invalid Nonce',
'Invalid Nonce',
array(
'back_link' => true,
)
);
}

if ( isset($_POST['action']) ) {
if ( 'mailrelay_save_authentication_settings' === $_POST['action'] ) {
$response = $this->process_save_connection_settings();
} elseif ( 'mailrelay_save_settings' === $_POST['action'] ) {
Expand Down Expand Up @@ -108,10 +119,11 @@ public function render_admin_page() {

<form method="post">
<?php
do_settings_sections( 'manual-page-admin' );
$attributes = array( 'onclick' => 'return check_form();' );
$submit_text = __( 'Sync', 'mailrelay' );
submit_button( $submit_text, 'primary', 'submit-manual', true, $attributes );
wp_nonce_field('_mailrelay_nonce', '_mailrelay_nonce');
do_settings_sections( 'manual-page-admin' );
$attributes = array( 'onclick' => 'return check_form();' );
$submit_text = __( 'Sync', 'mailrelay' );
submit_button( $submit_text, 'primary', 'submit-manual', true, $attributes );
?>
</form>
</div>
Expand All @@ -130,6 +142,7 @@ public function render_admin_page() {
<?php settings_errors(); ?>
<form method="post">
<?php
wp_nonce_field('_mailrelay_nonce', '_mailrelay_nonce');
do_settings_sections( 'mailrelay-authentication-page' );
$submit_text = __( 'Save', 'mailrelay' );
submit_button( $submit_text, 'primary', 'submit-authentication' );
Expand Down Expand Up @@ -158,6 +171,7 @@ public function render_admin_page() {

<form method="post">
<?php
wp_nonce_field('_mailrelay_nonce', '_mailrelay_nonce');
do_settings_sections( 'mailrelay-settings-page' );
$attributes = array( 'onclick' => 'return check_form();' );
$submit_text = __( 'Save', 'mailrelay' );
Expand Down Expand Up @@ -331,7 +345,8 @@ public function action_manual_sync_callback() {
}

public function auto_sync_callback() {
$value = isset( $_POST['mailrelay_auto_sync'] ) ? wp_unslash( $_POST['mailrelay_auto_sync'] ) : get_option( 'mailrelay_auto_sync' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification happens at render_admin_page.
$value = isset( $_POST['mailrelay_auto_sync'] ) ? filter_var( wp_unslash( $_POST['mailrelay_auto_sync'] ), FILTER_SANITIZE_NUMBER_INT ) : get_option( 'mailrelay_auto_sync' );
?>
<input type="checkbox" name="mailrelay_auto_sync" id="mailrelay_auto_sync" value="1" <?php checked( 1, $value ); ?>/>
<?php
Expand All @@ -342,7 +357,8 @@ public function groups_callback() {
$auto_groups = get_option( 'mailrelay_auto_sync_groups' );
$auto_groups = $auto_groups ? $auto_groups : array();

$mailrelay_auto_sync_groups = isset( $_POST['mailrelay_auto_sync_groups'] ) ? (array) wp_unslash( $_POST['mailrelay_auto_sync_groups'] ) : $auto_groups; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification happens at render_admin_page.
$mailrelay_auto_sync_groups = isset( $_POST['mailrelay_auto_sync_groups'] ) ? (array) wp_unslash( $_POST['mailrelay_auto_sync_groups'] ) : $auto_groups;

?>
<select multiple name="mailrelay_auto_sync_groups[]" id="mailrelay_auto_sync_groups" class="form-select">
Expand All @@ -366,7 +382,8 @@ public function woocommerce_callback() {
public function manual_groups_callback() {
$groups = mailrelay_get_groups();

$selected_groups = isset( $_POST['group'] ) ? (array) wp_unslash( $_POST['group'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification happens at render_admin_page.
$selected_groups = isset( $_POST['group'] ) ? (array) wp_unslash( $_POST['group'] ) : array();

?>
<select multiple name="group[]" id="mailrelay_group" class="form-select">
Expand Down Expand Up @@ -405,14 +422,17 @@ protected function mailrelay_data() {
public function process_save_connection_settings() {
$mailrelay_data = array();

$mailrelay_data['host'] = isset( $_POST['mailrelay_host'] ) ? wp_unslash( $_POST['mailrelay_host'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification happens at render_admin_page.
$mailrelay_data['host'] = isset( $_POST['mailrelay_host'] ) ? sanitize_text_field( wp_unslash( $_POST['mailrelay_host'] ) ) : '';
if ( strpos( $mailrelay_data['host'], 'http://' ) === 0 || strpos( $mailrelay_data['host'], 'https://' ) === 0 ) {
$mailrelay_data['host'] = wp_parse_url( $mailrelay_data['host'], PHP_URL_HOST );
}
if ( strpos( $mailrelay_data['host'], '.ipzmarketing.com' ) !== false ) {
$mailrelay_data['host'] = str_replace( '.ipzmarketing.com', '', $mailrelay_data['host'] );
}
$mailrelay_data['api_key'] = ( isset( $_POST['mailrelay_api_key'] ) ) ? wp_unslash( $_POST['mailrelay_api_key'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification happens at render_admin_page.
$mailrelay_data['api_key'] = ( isset( $_POST['mailrelay_api_key'] ) ) ? sanitize_text_field( wp_unslash( $_POST['mailrelay_api_key'] ) ) : '';

$ping_response_code = mailrelay_ping( $mailrelay_data );

Expand Down Expand Up @@ -455,8 +475,11 @@ public function process_save_connection_settings() {
public function process_save_settings() {
$mailrelay_data = array();

$mailrelay_data['mailrelay_auto_sync'] = ( isset( $_POST['mailrelay_auto_sync'] ) ) ? wp_unslash( $_POST['mailrelay_auto_sync'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$mailrelay_data['mailrelay_auto_sync_groups'] = ( isset( $_POST['mailrelay_auto_sync_groups'] ) ) ? wp_unslash( $_POST['mailrelay_auto_sync_groups'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification happens at render_admin_page.
$mailrelay_data['mailrelay_auto_sync'] = ( isset( $_POST['mailrelay_auto_sync'] ) ) ? filter_var( wp_unslash( $_POST['mailrelay_auto_sync'] ), FILTER_SANITIZE_NUMBER_INT ) : false;

// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification happens at render_admin_page.
$mailrelay_data['mailrelay_auto_sync_groups'] = ( isset( $_POST['mailrelay_auto_sync_groups'] ) ) ? wp_unslash( $_POST['mailrelay_auto_sync_groups'] ) : array();

update_option( 'mailrelay_auto_sync', $mailrelay_data['mailrelay_auto_sync'] );
update_option( 'mailrelay_auto_sync_groups', $mailrelay_data['mailrelay_auto_sync_groups'] );
Expand All @@ -468,6 +491,7 @@ public function process_save_settings() {
}

public function process_manual_sync() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: Nonce verification happens at render_admin_page.
$woo_commerce_option = ( isset( $_REQUEST['woo_commerce'] ) ) ? sanitize_key( wp_unslash( $_REQUEST['woo_commerce'] ) ) : '';

if ( 'only' === $woo_commerce_option ) {
Expand All @@ -484,6 +508,7 @@ public function process_manual_sync() {
$users = get_users();
}

// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: Nonce verification happens at render_admin_page.
$groups = isset( $_REQUEST['group'] ) ? array_map( 'intval', wp_unslash( $_REQUEST['group'] ) ) : array();
$added = 0;
$updated = 0;
Expand Down
3 changes: 0 additions & 3 deletions phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
<description>Generally-applicable sniffs for WordPress plugins</description>

<rule ref="WordPress">
<exclude name="WordPress.Security.NonceVerification.Recommended" />
<exclude name="WordPress.Security.NonceVerification.Missing" />

<exclude name="Generic.Formatting.MultipleStatementAlignment.NotSameWarning" />

<exclude name="Squiz.Commenting.ClassComment.Missing" />
Expand Down

0 comments on commit fa562b5

Please sign in to comment.