Make WordPress Core


Ignore:
Timestamp:
11/14/2016 07:12:31 AM (10 years ago)
Author:
rmccue
Message:

REST API: Improve validation for usernames and passwords.

Also improves the slashing of user data in the REST API to avoid data loss.

Props jnylen0.
Fixes #38739.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php

    r39177 r39219  
    418418
    419419                        if ( is_wp_error( $ret['errors'] ) && ! empty( $ret['errors']->errors ) ) {
    420                                 return $ret['errors'];
     420                                $error = new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) );
     421                                foreach ( $ret['errors']->errors as $code => $messages ) {
     422                                        foreach ( $messages as $message ) {
     423                                                $error->add( $code, $message );
     424                                        }
     425                                        if ( $error_data = $error->get_error_data( $code ) ) {
     426                                                $error->add_data( $error_data, $code );
     427                                        }
     428                                }
     429                                return $error;
    421430                        }
    422431                }
    … …  
    430439
    431440                        $user->ID = $user_id;
    432                         $user_id  = wp_update_user( $user );
     441                        $user_id  = wp_update_user( wp_slash( (array) $user ) );
    433442
    434443                        if ( is_wp_error( $user_id ) ) {
    … …  
    438447                        add_user_to_blog( get_site()->id, $user_id, '' );
    439448                } else {
    440                         $user_id = wp_insert_user( $user );
     449                        $user_id = wp_insert_user( wp_slash( (array) $user ) );
    441450
    442451                        if ( is_wp_error( $user_id ) ) {
    … …  
    553562                $user->ID = $id;
    554563
    555                 $user_id = wp_update_user( $user );
     564                $user_id = wp_update_user( wp_slash( (array) $user ) );
    556565
    557566                if ( is_wp_error( $user_id ) ) {
    … …  
    9951004
    9961005                return true;
     1006        }
     1007
     1008        /**
     1009         * Check a username for the REST API.
     1010         *
     1011         * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
     1012         *
     1013         * @since 4.7.0
     1014         *
     1015         * @param  mixed            $value   The username submitted in the request.
     1016         * @param  WP_REST_Request  $request Full details about the request.
     1017         * @param  string           $param   The parameter name.
     1018         * @return WP_Error|string The sanitized username, if valid, otherwise an error.
     1019         */
     1020        public function check_username( $value, $request, $param ) {
     1021                $username = (string) rest_sanitize_value_from_schema( $value, $request, $param );
     1022
     1023                if ( ! validate_username( $username ) ) {
     1024                        return new WP_Error( 'rest_user_invalid_username', __( 'Username contains invalid characters.' ), array( 'status' => 400 ) );
     1025                }
     1026
     1027                /** This filter is documented in wp-includes/user.php */
     1028                $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
     1029
     1030                if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ) ) ) {
     1031                        return new WP_Error( 'rest_user_invalid_username', __( 'Sorry, that username is not allowed.' ), array( 'status' => 400 ) );
     1032                }
     1033
     1034                return $username;
     1035        }
     1036
     1037        /**
     1038         * Check a user password for the REST API.
     1039         *
     1040         * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
     1041         *
     1042         * @since 4.7.0
     1043         *
     1044         * @param  mixed            $value   The password submitted in the request.
     1045         * @param  WP_REST_Request  $request Full details about the request.
     1046         * @param  string           $param   The parameter name.
     1047         * @return WP_Error|string The sanitized password, if valid, otherwise an error.
     1048         */
     1049        public function check_user_password( $value, $request, $param ) {
     1050                $password = (string) rest_sanitize_value_from_schema( $value, $request, $param );
     1051
     1052                if ( empty( $password ) ) {
     1053                        return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot be empty.' ), array( 'status' => 400 ) );
     1054                }
     1055
     1056                if ( false !== strpos( $password, "\\" ) ) {
     1057                        return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot contain the "\\" character.' ), array( 'status' => 400 ) );
     1058                }
     1059
     1060                return $password;
    9971061        }
    9981062
    … …  
    10231087                                        'required'    => true,
    10241088                                        'arg_options' => array(
    1025                                                 'sanitize_callback' => 'sanitize_user',
     1089                                                'sanitize_callback' => array( $this, 'check_username' ),
    10261090                                        ),
    10271091                                ),
    … …  
    10671131                                        'type'        => 'string',
    10681132                                        'context'     => array( 'embed', 'view', 'edit' ),
    1069                                         'arg_options' => array(
    1070                                                 'sanitize_callback' => 'wp_filter_post_kses',
    1071                                         ),
    10721133                                ),
    10731134                                'link'        => array(
    … …  
    11201181                                        'context'     => array(), // Password is never displayed.
    11211182                                        'required'    => true,
     1183                                        'arg_options' => array(
     1184                                                'sanitize_callback' => array( $this, 'check_user_password' ),
     1185                                        ),
    11221186                                ),
    11231187                                'capabilities'    => array(
Note: See TracChangeset for help on using the changeset viewer.