Skip to content

Commit 59e4968

Browse files
committed
Merge branch 'master' into develop
2 parents 90ecc07 + 4903f83 commit 59e4968

File tree

6 files changed

+78
-64
lines changed

6 files changed

+78
-64
lines changed

classes/class-network.php

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ class Network {
2727
public $network_settings_page_slug = 'wp_stream_network_settings';
2828

2929
/**
30-
* Default setting page slug
30+
* The option name for the network settings.
3131
*
3232
* @var string
3333
*/
34-
public $default_settings_page_slug = 'wp_stream_default_settings';
34+
public $network_settings_option = 'wp_stream_network';
3535

3636
/**
3737
* Class constructor
@@ -225,13 +225,8 @@ public function settings_form_description( $description ) {
225225

226226
$current_page = wp_stream_filter_input( INPUT_GET, 'page' );
227227

228-
switch ( $current_page ) {
229-
case $this->network_settings_page_slug:
230-
$description = __( 'These settings apply to all sites on the network.', 'stream' );
231-
break;
232-
case $this->default_settings_page_slug:
233-
$description = __( 'These default settings will apply to new sites created on the network. These settings do not alter existing sites.', 'stream' );
234-
break;
228+
if ( $this->network_settings_page_slug === $current_page ) {
229+
$description = __( 'These settings apply to all sites on the network.', 'stream' );
235230
}
236231

237232
return $description;
@@ -351,46 +346,42 @@ public function get_settings_translations( $labels ) {
351346
* Wrapper for the settings API to work on the network settings page
352347
*/
353348
public function network_options_action() {
354-
$allowed_referrers = array(
355-
$this->network_settings_page_slug,
356-
$this->default_settings_page_slug,
357-
);
358349

359-
// @codingStandardsIgnoreLine
360-
if ( ! isset( $_GET['action'] ) || ! in_array( $_GET['action'], $allowed_referrers, true ) ) {
350+
// Check the nonce.
351+
if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], sprintf( '%s-options', $this->network_settings_option ) ) ) {
352+
return;
353+
}
354+
355+
// Check the user capability.
356+
if ( ! current_user_can( $this->plugin->admin->settings_cap ) ) {
357+
return;
358+
}
359+
360+
// Check the action.
361+
if ( ! isset( $_GET['action'] ) || $this->network_settings_page_slug !== $_GET['action'] ) {
361362
return;
362363
}
363364

364-
// @codingStandardsIgnoreLine
365-
$options = isset( $_POST['option_page'] ) ? explode( ',', stripslashes( $_POST['option_page'] ) ) : null;
365+
$option = ! empty( $_POST['option_page'] ) ? $_POST['option_page'] : false;
366366

367-
if ( $options ) {
367+
if ( $option && $this->network_settings_option === $option ) {
368368

369-
foreach ( $options as $option ) {
370-
$option = trim( $option );
371-
$value = null;
372-
$sections = $this->plugin->settings->get_fields();
369+
$value = array();
370+
$sections = $this->plugin->settings->get_fields();
373371

374-
foreach ( $sections as $section_name => $section ) {
375-
foreach ( $section['fields'] as $field_idx => $field ) {
376-
$option_key = $section_name . '_' . $field['name'];
372+
foreach ( $sections as $section_name => $section ) {
373+
foreach ( $section['fields'] as $field_idx => $field ) {
374+
$option_key = $section_name . '_' . $field['name'];
377375

378-
// @codingStandardsIgnoreStart
379-
if ( isset( $_POST[ $option ][ $option_key ] ) ) {
380-
$value[ $option_key ] = $_POST[ $option ][ $option_key ];
381-
} else {
382-
$value[ $option_key ] = false;
383-
}
384-
// @codingStandardsIgnoreEnd
376+
if ( isset( $_POST[ $option ][ $option_key ] ) ) {
377+
$value[ $option_key ] = $this->plugin->settings->sanitize_setting_by_field_type( $_POST[ $option ][ $option_key ], $field['type'] );
378+
} else {
379+
$value[ $option_key ] = false;
385380
}
386381
}
387-
388-
if ( ! is_array( $value ) ) {
389-
$value = trim( $value );
390-
}
391-
392-
update_site_option( $option, $value );
393382
}
383+
384+
update_site_option( $this->network_settings_option, $value );
394385
}
395386

396387
if ( ! count( get_settings_errors() ) ) {

classes/class-plugin.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Plugin {
2020
*
2121
* @const string
2222
*/
23-
const VERSION = '4.0.1';
23+
const VERSION = '4.0.2';
2424

2525
/**
2626
* WP-CLI command

classes/class-settings.php

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -573,35 +573,50 @@ public function sanitize_settings( $input ) {
573573
continue;
574574
}
575575

576-
// Sanitize depending on the type of field.
577-
switch ( $type ) {
578-
case 'number':
579-
$output[ $name ] = is_numeric( $input[ $name ] ) ? intval( trim( $input[ $name ] ) ) : '';
580-
break;
581-
case 'checkbox':
582-
$output[ $name ] = is_numeric( $input[ $name ] ) ? absint( trim( $input[ $name ] ) ) : '';
583-
break;
584-
default:
585-
if ( is_array( $input[ $name ] ) ) {
586-
$output[ $name ] = $input[ $name ];
587-
588-
// Support all values in multidimentional arrays too.
589-
array_walk_recursive(
590-
$output[ $name ],
591-
function ( &$v ) {
592-
$v = sanitize_text_field( trim( $v ) );
593-
}
594-
);
595-
} else {
596-
$output[ $name ] = sanitize_text_field( trim( $input[ $name ] ) );
597-
}
598-
}
576+
$output[ $name ] = $this->sanitize_setting_by_field_type( $input[ $name ], $type );
599577
}
600578
}
601579

602580
return $output;
603581
}
604582

583+
/**
584+
* Sanitizes a setting value based on the field type.
585+
*
586+
* @param mixed $value The value to be sanitized.
587+
* @param string $field_type The type of field.
588+
*
589+
* @return mixed The sanitized value.
590+
*/
591+
public function sanitize_setting_by_field_type( $value, $field_type ) {
592+
593+
// Sanitize depending on the type of field.
594+
switch ( $field_type ) {
595+
case 'number':
596+
$sanitized_value = is_numeric( $value ) ? intval( trim( $value ) ) : '';
597+
break;
598+
case 'checkbox':
599+
$sanitized_value = is_numeric( $value ) ? absint( trim( $value ) ) : '';
600+
break;
601+
default:
602+
if ( is_array( $value ) ) {
603+
$sanitized_value = $value;
604+
605+
// Support all values in multidimentional arrays too.
606+
array_walk_recursive(
607+
$sanitized_value,
608+
function ( &$v ) {
609+
$v = sanitize_text_field( trim( $v ) );
610+
}
611+
);
612+
} else {
613+
$sanitized_value = sanitize_text_field( trim( $value ) );
614+
}
615+
}
616+
617+
return $sanitized_value;
618+
}
619+
605620
/**
606621
* Compile HTML needed for displaying the field
607622
*

docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ services:
77
ports:
88
- "3306:3306"
99
restart: always
10+
ports:
11+
- "3306:3306"
1012
environment:
1113
MYSQL_DATABASE: wordpress
1214
MYSQL_USER: wordpress

readme.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Contributors: xwp
33
Tags: wp stream, stream, activity, logs, track
44
Requires at least: 4.6
55
Tested up to: 6.6
6-
Stable tag: 4.0.1
6+
Stable tag: 4.0.2
77
License: GPLv2 or later
88
License URI: https://www.gnu.org/licenses/gpl-2.0.html
99

@@ -134,6 +134,12 @@ Use only `$_SERVER['REMOTE_ADDR']` as the client IP address for event logs witho
134134

135135
== Changelog ==
136136

137+
= 4.0.2 - August 22, 2024 =
138+
139+
**Security update**
140+
141+
- Fix vulnerability which allowed logged in users to update some site options in certain configurations. Props to [@sybrew](https://github.com/sybrew) for responsibly disclosing this issue.
142+
137143
= 4.0.1 - July 30, 2024 =
138144

139145
**Bug fixes**

stream.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Plugin Name: Stream
44
* Plugin URI: https://xwp.co/work/stream/
55
* Description: Stream tracks logged-in user activity so you can monitor every change made on your WordPress site in beautifully organized detail. All activity is organized by context, action and IP address for easy filtering. Developers can extend Stream with custom connectors to log any kind of action.
6-
* Version: 4.0.1
6+
* Version: 4.0.2
77
* Author: XWP
88
* Author URI: https://xwp.co
99
* License: GPLv2+

0 commit comments

Comments
 (0)