Make WordPress Core

Changeset 56844 for branches/6.3


Ignore:
Timestamp:
10/12/2023 01:24:56 PM (3 years ago)
Author:
audrasjb
Message:

Application Passwords: Prevent the use of some pseudo protocols in application passwords.

Props tykoted, xknown, peterwilsoncc, jorbin, timothyblynjacobs, martinkrcho, paulkevan, dd32, ehtis.
Merges [56837] to the 6.3 branch.

Location:
branches/6.3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/6.3

  • branches/6.3/src/wp-admin/includes/user.php

    r55988 r56844  
    637637 * @since 5.6.0
    638638 * @since 6.2.0 Allow insecure HTTP connections for the local environment.
     639 * @since 6.3.2 Validates the success and reject URLs to prevent javascript pseudo protocol being executed.
    639640 *
    640641 * @param array   $request {
     
    650651 */
    651652function wp_is_authorize_application_password_request_valid( $request, $user ) {
    652         $error    = new WP_Error();
    653         $is_local = 'local' === wp_get_environment_type();
    654 
    655         if ( ! empty( $request['success_url'] ) ) {
    656                 $scheme = wp_parse_url( $request['success_url'], PHP_URL_SCHEME );
    657 
    658                 if ( 'http' === $scheme && ! $is_local ) {
     653        $error = new WP_Error();
     654
     655        if ( isset( $request['success_url'] ) ) {
     656                $validated_success_url = wp_is_authorize_application_redirect_url_valid( $request['success_url'] );
     657                if ( is_wp_error( $validated_success_url ) ) {
    659658                        $error->add(
    660                                 'invalid_redirect_scheme',
    661                                 __( 'The success URL must be served over a secure connection.' )
     659                                $validated_success_url->get_error_code(),
     660                                $validated_success_url->get_error_message()
    662661                        );
    663662                }
    664663        }
    665664
    666         if ( ! empty( $request['reject_url'] ) ) {
    667                 $scheme = wp_parse_url( $request['reject_url'], PHP_URL_SCHEME );
    668 
    669                 if ( 'http' === $scheme && ! $is_local ) {
     665        if ( isset( $request['reject_url'] ) ) {
     666                $validated_reject_url = wp_is_authorize_application_redirect_url_valid( $request['reject_url'] );
     667                if ( is_wp_error( $validated_reject_url ) ) {
    670668                        $error->add(
    671                                 'invalid_redirect_scheme',
    672                                 __( 'The rejection URL must be served over a secure connection.' )
     669                                $validated_reject_url->get_error_code(),
     670                                $validated_reject_url->get_error_message()
    673671                        );
    674672                }
     
    699697        return true;
    700698}
     699
     700/**
     701 * Validates the redirect URL protocol scheme. The protocol can be anything except http and javascript.
     702 *
     703 * @since 6.3.2
     704 *
     705 * @param string $url - The redirect URL to be validated.
     706 *
     707 * @return true|WP_Error True if the redirect URL is valid, a WP_Error object otherwise.
     708 */
     709function wp_is_authorize_application_redirect_url_valid( $url ) {
     710        $bad_protocols = array( 'javascript', 'data' );
     711        if ( empty( $url ) ) {
     712                return true;
     713        }
     714
     715        // Based on https://www.rfc-editor.org/rfc/rfc2396#section-3.1
     716        $valid_scheme_regex = '/^[a-zA-Z][a-zA-Z0-9+.-]*:/';
     717        if ( ! preg_match( $valid_scheme_regex, $url ) ) {
     718                return new WP_Error(
     719                        'invalid_redirect_url_format',
     720                        __( 'Invalid URL format.' )
     721                );
     722        }
     723
     724        /**
     725         * Filters the list of invalid protocols used in applications redirect URLs.
     726         *
     727         * @since 6.3.2
     728         *
     729         * @param string[]  $bad_protocols Array of invalid protocols.
     730         * @param string    $url The redirect URL to be validated.
     731         */
     732        $invalid_protocols = array_map( 'strtolower', apply_filters( 'wp_authorize_application_redirect_url_invalid_protocols', $bad_protocols, $url ) );
     733
     734        $scheme   = wp_parse_url( $url, PHP_URL_SCHEME );
     735        $host     = wp_parse_url( $url, PHP_URL_HOST );
     736        $is_local = 'local' === wp_get_environment_type();
     737
     738        // validates if the proper URI format is applied to the $url
     739        if ( empty( $host ) || empty( $scheme ) || in_array( strtolower( $scheme ), $invalid_protocols, true ) ) {
     740                return new WP_Error(
     741                        'invalid_redirect_url_format',
     742                        __( 'Invalid URL format.' )
     743                );
     744        }
     745
     746        if ( 'http' === $scheme && ! $is_local ) {
     747                return new WP_Error(
     748                        'invalid_redirect_scheme',
     749                        __( 'The URL must be served over a secure connection.' )
     750                );
     751        }
     752
     753        return true;
     754}
Note: See TracChangeset for help on using the changeset viewer.