WordPress.org

Make WordPress Core


Ignore:
Timestamp:
10/23/2015 04:45:10 AM (6 years ago)
Author:
dd32
Message:

XMLRPC: Prevent authentication from occuring after a failed authentication attmept in any single XML-RPC call.

This hardens WordPress against a common vector which uses multiple user identifiers in a single system.multicall call. In the event that authentication fails, all following authentication attempts in that call will also fail.

Props dd32, johnbillion.
Fixes #34336

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/xmlrpc/basic.php

    r25002 r35366  
    2020        $user_id = $this->make_user_by_role( 'subscriber' );
    2121
     22        $this->assertTrue( $this->myxmlrpcserver->login_pass_ok( 'subscriber', 'subscriber' ) );
     23        $this->assertInstanceOf( 'WP_User', $this->myxmlrpcserver->login( 'subscriber', 'subscriber' ) );
     24    }
     25
     26    function test_login_pass_bad() {
     27        $user_id = $this->make_user_by_role( 'subscriber' );
     28
    2229        $this->assertFalse( $this->myxmlrpcserver->login_pass_ok( 'username', 'password' ) );
    2330        $this->assertFalse( $this->myxmlrpcserver->login( 'username', 'password' ) );
    2431
    25         $this->assertTrue( $this->myxmlrpcserver->login_pass_ok( 'subscriber', 'subscriber' ) );
    26         $this->assertInstanceOf( 'WP_User', $this->myxmlrpcserver->login( 'subscriber', 'subscriber' ) );
     32        // The auth will still fail due to authentication blocking after the first failed attempt
     33        $this->assertFalse( $this->myxmlrpcserver->login_pass_ok( 'subscriber', 'subscriber' ) );
     34    }
     35
     36    /**
     37     * @ticket 34336
     38     */
     39    function test_multicall_invalidates_all_calls_after_invalid_call() {
     40        $editor_id = $this->make_user_by_role( 'editor' );
     41        $post_id = self::factory()->post->create( array(
     42            'post_author' => $editor_id,
     43        ) );
     44
     45        $method_calls = array(
     46            // Valid login
     47            array(
     48                'methodName' => 'wp.editPost',
     49                'params'     => array(
     50                    0,
     51                    'editor',
     52                    'editor',
     53                    $post_id,
     54                    array(
     55                        'title' => 'Title 1',
     56                    ),
     57                ),
     58            ),
     59            // *Invalid* login
     60            array(
     61                'methodName' => 'wp.editPost',
     62                'params'     => array(
     63                    0,
     64                    'editor',
     65                    'password',
     66                    $post_id,
     67                    array(
     68                        'title' => 'Title 2',
     69                    ),
     70                ),
     71            ),
     72            // Valid login
     73            array(
     74                'methodName' => 'wp.editPost',
     75                'params'     => array(
     76                    0,
     77                    'editor',
     78                    'editor',
     79                    $post_id,
     80                    array(
     81                        'title' => 'Title 3',
     82                    ),
     83                ),
     84            ),
     85        );
     86
     87        $this->myxmlrpcserver->callbacks = $this->myxmlrpcserver->methods;
     88
     89        $result = $this->myxmlrpcserver->multiCall( $method_calls );
     90
     91        $this->assertArrayNotHasKey( 'faultCode', $result[0] );
     92        $this->assertArrayHasKey( 'faultCode', $result[1] );
     93        $this->assertArrayHasKey( 'faultCode', $result[2] );
     94
    2795    }
    2896}
Note: See TracChangeset for help on using the changeset viewer.