| @@ -55,8 +55,26 @@ | ||
| 55 | 55 | |
| 56 | 56 | public function load_ajax_widget() { |
| 57 | 57 | $_POST = wp_unslash( $_POST ); |
| 58 | 58 | $instance = json_decode( (string) wpfval( $_POST, 'instance' ), true ); |
| 59 | + | |
| 60 | + // SECURITY: Sanitize instance parameters | |
| 61 | + if( is_array( $instance ) ) { | |
| 62 | + // Intersect groupids with visible usergroups to prevent hidden group enumeration | |
| 63 | + if( isset( $instance['groupids'] ) ) { | |
| 64 | + $visible_groupids = WPF()->usergroup->get_visible_usergroup_ids(); | |
| 65 | + $instance['groupids'] = array_values( array_intersect( | |
| 66 | + array_map( 'intval', (array) $instance['groupids'] ), | |
| 67 | + $visible_groupids | |
| 68 | + ) ); | |
| 69 | + } | |
| 70 | + | |
| 71 | + // Cap count to prevent resource exhaustion | |
| 72 | + if( isset( $instance['count'] ) ) { | |
| 73 | + $instance['count'] = min( 50, max( 1, intval( $instance['count'] ) ) ); | |
| 74 | + } | |
| 75 | + } | |
| 76 | + | |
| 59 | 77 | wp_send_json_success( ['html' => $this->get_widget( $instance )] ); |
| 60 | 78 | } |
| 61 | 79 | |
| 62 | 80 | public function widget( $args, $instance ) { |