PluginProbe
Stream – Activity Log & Audit Trail / 4.0.2
Stream – Activity Log & Audit Trail v4.0.2
4.4.0 4.3.0 4.2.2 4.2.1 trunk 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.1 3.1.1 3.10.0 3.2.0 3.2.1 3.2.2 3.2.3 All 50 releases
← All changes | classes/class-network.php +10 -64 trunk4.0.2 View file →
@@ -83,21 +83,14 @@
83 83 *
84 84 * @see https://core.trac.wordpress.org/ticket/22589
85 85 */
86 86 public function ajax_network_admin() {
87 - $http_referer = isset( $_SERVER['HTTP_REFERER'] ) ? esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : '';
88 -
89 - // Prefer filterable `wp_doing_ajax()` (WP 4.7+); the plugin supports 4.6.
90 - $doing_ajax = function_exists( 'wp_doing_ajax' )
91 - ? wp_doing_ajax()
92 - : ( defined( 'DOING_AJAX' ) && DOING_AJAX );
93 -
94 87 if (
95 - $doing_ajax
88 + defined( 'DOING_AJAX' )
96 89 &&
97 - 0 === stripos( $http_referer, network_admin_url() )
90 + DOING_AJAX
98 91 &&
99 - $this->can_view_network_records()
92 + preg_match( '#^' . network_admin_url() . '#i', $_SERVER['HTTP_REFERER'] )
100 93 ) {
101 94 define( 'WP_NETWORK_ADMIN', true );
102 95 return WP_NETWORK_ADMIN;
103 96 }
@@ -105,36 +98,8 @@
105 98 return false;
106 99 }
107 100
108 101 /**
109 - * Whether the current user is allowed to read records across the whole
110 - * network (and to be treated as being in the Network Admin).
111 - *
112 - * The Referer prefix checked in ajax_network_admin() is caller-controlled,
113 - * so it can only ever be a UI hint about where a request came from -- never
114 - * a source of authority. Network-wide record access additionally requires a
115 - * real network capability, otherwise a site-level Stream viewer could spoof
116 - * the header to lift the per-blog restriction applied in
117 - * network_query_args() or to have their actions logged against blog_id 0.
118 - *
119 - * @return bool
120 - */
121 - public function can_view_network_records() {
122 - if ( ! is_multisite() ) {
123 - return false;
124 - }
125 -
126 - // WP-CLI runs with shell-level access and usually with no logged-in
127 - // user, so capability checks would fail for a legitimate operator and
128 - // break `wp stream query --blog_id=N`. It sits outside this boundary.
129 - if ( defined( 'WP_CLI' ) && WP_CLI ) {
130 - return true;
131 - }
132 -
133 - return current_user_can( 'manage_network_options' );
134 - }
135 -
136 - /**
137 102 * Builds a stdClass object used when displaying actions done in network administration
138 103 *
139 104 * @return object
140 105 */
@@ -382,13 +347,9 @@
382 347 */
383 348 public function network_options_action() {
384 349
385 350 // Check the nonce.
386 - if (
387 - empty( $_POST['_wpnonce'] )
388 - ||
389 - ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), sprintf( '%s-options', $this->network_settings_option ) )
390 - ) {
351 + if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], sprintf( '%s-options', $this->network_settings_option ) ) ) {
391 352 return;
392 353 }
393 354
394 355 // Check the user capability.
@@ -396,27 +357,25 @@
396 357 return;
397 358 }
398 359
399 360 // Check the action.
400 - $action = isset( $_GET['action'] ) ? sanitize_key( wp_unslash( $_GET['action'] ) ) : '';
401 - if ( $this->network_settings_page_slug !== $action ) {
361 + if ( ! isset( $_GET['action'] ) || $this->network_settings_page_slug !== $_GET['action'] ) {
402 362 return;
403 363 }
404 364
405 - $option = ! empty( $_POST['option_page'] ) ? sanitize_key( wp_unslash( $_POST['option_page'] ) ) : false;
365 + $option = ! empty( $_POST['option_page'] ) ? $_POST['option_page'] : false;
406 366
407 367 if ( $option && $this->network_settings_option === $option ) {
408 368
409 - $value = array();
410 - $posted_options = isset( $_POST[ $option ] ) && is_array( $_POST[ $option ] ) ? wp_unslash( $_POST[ $option ] ) : array();
411 - $sections = $this->plugin->settings->get_fields();
369 + $value = array();
370 + $sections = $this->plugin->settings->get_fields();
412 371
413 372 foreach ( $sections as $section_name => $section ) {
414 373 foreach ( $section['fields'] as $field_idx => $field ) {
415 374 $option_key = $section_name . '_' . $field['name'];
416 375
417 - if ( isset( $posted_options[ $option_key ] ) ) {
418 - $value[ $option_key ] = $this->plugin->settings->sanitize_setting_by_field_type( $posted_options[ $option_key ], $field['type'] );
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'] );
419 378 } else {
420 379 $value[ $option_key ] = false;
421 380 }
422 381 }
@@ -533,21 +492,8 @@
533 492 * @return array
534 493 */
535 494 public function network_query_args( $args ) {
536 495 $args['site_id'] = is_numeric( $args['site_id'] ) ? $args['site_id'] : get_current_site()->id;
537 -
538 - // Only users with a network capability may choose which blog to read
539 - // from. For everyone else the requested blog_id is ignored entirely and
540 - // forced to the current blog: a numeric type check is not an
541 - // authorization check, and the Stream tables are shared across the
542 - // whole network, so honouring an arbitrary ?blog_id= would let a
543 - // site-level viewer read another site's activity.
544 - if ( ! $this->can_view_network_records() ) {
545 - $args['blog_id'] = get_current_blog_id();
546 -
547 - return $args;
548 - }
549 -
550 496 $args['blog_id'] = is_numeric( $args['blog_id'] ) ? $args['blog_id'] : ( is_network_admin() ? null : get_current_blog_id() );
551 497
552 498 return $args;
553 499 }