WordPress.org

Make WordPress Core

Changeset 50030


Ignore:
Timestamp:
01/27/2021 07:03:42 PM (10 months ago)
Author:
TimothyBlynJacobs
Message:

App Passwords: Improve validation and sanitization of the application name.

Application names are now required to be unique and cannot contain solely whitespace characters. Additionally, invalid characters are now stripped from the application name using sanitize_text_field().

Props Boniu91, hellofromTonya, engahmeds3ed, xkon, francina.
Fixes #51941.

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/js/_enqueues/admin/application-passwords.js

    r50001 r50030  
    5858
    5959            $newAppPassForm.after( tmplNewAppPass( {
    60                 name: name,
     60                name: response.name,
    6161                password: response.password
    6262            } ) );
  • trunk/src/js/_enqueues/admin/auth-app.js

    r49920 r50030  
    9999
    100100                // We're using .text() to write the variables to avoid any chance of XSS.
    101                 $( 'strong', $notice ).text( name );
     101                $( 'strong', $notice ).text( response.name );
    102102                $( 'input', $notice ).val( response.password );
    103103
  • trunk/src/wp-includes/class-wp-application-passwords.php

    r49787 r50030  
    5959     *
    6060     * @since 5.6.0
     61     * @since 5.7.0 Returns WP_Error if application name already exists.
    6162     *
    6263     * @param int   $user_id  User ID.
     
    6667     */
    6768    public static function create_new_application_password( $user_id, $args = array() ) {
     69        if ( ! empty( $args['name'] ) ) {
     70            $args['name'] = sanitize_text_field( $args['name'] );
     71        }
     72
    6873        if ( empty( $args['name'] ) ) {
    69             return new WP_Error( 'application_password_empty_name', __( 'An application name is required to create an application password.' ) );
     74            return new WP_Error( 'application_password_empty_name', __( 'An application name is required to create an application password.' ), array( 'status' => 400 ) );
     75        }
     76
     77        if ( self::application_name_exists_for_user( $user_id, $args['name'] ) ) {
     78            return new WP_Error( 'application_password_duplicate_name', __( 'Each application name should be unique.' ), array( 'status' => 409 ) );
    7079        }
    7180
     
    164173
    165174    /**
     175     * Check if application name exists before for this user.
     176     *
     177     * @since 5.7.0
     178     *
     179     * @param int    $user_id User ID.
     180     * @param string $name    Application name.
     181     *
     182     * @return bool Provided application name exists or not.
     183     */
     184    public static function application_name_exists_for_user( $user_id, $name ) {
     185        $passwords = static::get_user_application_passwords( $user_id );
     186
     187        foreach ( $passwords as $password ) {
     188            if ( strtolower( $password['name'] ) === strtolower( $name ) ) {
     189                return true;
     190            }
     191        }
     192
     193        return false;
     194    }
     195
     196    /**
    166197     * Updates an application password.
    167198     *
     
    179210            if ( $item['uuid'] !== $uuid ) {
    180211                continue;
     212            }
     213
     214            if ( ! empty( $update['name'] ) ) {
     215                $update['name'] = sanitize_text_field( $update['name'] );
    181216            }
    182217
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php

    r49617 r50030  
    632632                    'required'    => true,
    633633                    'context'     => array( 'view', 'edit', 'embed' ),
     634                    'minLength'   => 1,
     635                    'pattern'     => '.*\S.*',
    634636                ),
    635637                'password'  => array(
  • trunk/tests/phpunit/tests/rest-api/rest-application-passwords-controller.php

    r49752 r50030  
    539539    /**
    540540     * @ticket 51583
     541     * @ticket 51941
    541542     */
    542543    public function test_update_item_cannot_overwrite_app_id() {
     
    555556            self::$admin,
    556557            array(
    557                 'name'   => 'App',
     558                'name'   => 'App 2',
    558559                'app_id' => $app_id,
    559560            )
  • trunk/tests/qunit/fixtures/wp-api-generated.js

    r50024 r50030  
    49754975                            "description": "The name of the application password.",
    49764976                            "type": "string",
     4977                            "minLength": 1,
     4978                            "pattern": ".*\\S.*",
    49774979                            "required": true
    49784980                        }
     
    50315033                            "description": "The name of the application password.",
    50325034                            "type": "string",
     5035                            "minLength": 1,
     5036                            "pattern": ".*\\S.*",
    50335037                            "required": false
    50345038                        }
Note: See TracChangeset for help on using the changeset viewer.