Make WordPress Core


Ignore:
Timestamp:
07/21/2020 12:01:10 PM (4 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Issue a _doing_it_wrong when registering a route without a permission callback.

The REST API treats routes without a permission_callback as public. Because this happens without any warning to the user, if the permission callback is unintentionally omitted or misspelled, the endpoint can end up being available to the public. Such a scenario has happened multiple times in the wild, and the results can be catostrophic when it occurs.

For REST API routes that are intended to be public, it is recommended to set the permission callback to the __return_true built in function.

Fixes #50075.
Props rmccue, sorenbronsted, whyisjake, SergeyBiryukov, TimothyBlynJacobs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/rest-server.php

    r47351 r48526  
    6767            '/test',
    6868            array(
    69                 'methods'  => array( 'GET' ),
    70                 'callback' => '__return_null',
    71                 'args'     => array(
     69                'methods'             => array( 'GET' ),
     70                'callback'            => '__return_null',
     71                'permission_callback' => '__return_true',
     72                'args'                => array(
    7273                    'foo' => array(
    7374                        'default' => 'bar',
     
    8990            '/test',
    9091            array(
    91                 'methods'  => array( 'GET' ),
    92                 'callback' => '__return_null',
    93                 'args'     => array(
     92                'methods'             => array( 'GET' ),
     93                'callback'            => '__return_null',
     94                'permission_callback' => '__return_true',
     95                'args'                => array(
    9496                    'foo' => array(
    9597                        'default' => 'bar',
     
    111113            '/test',
    112114            array(
    113                 'methods'  => array( 'GET' ),
    114                 'callback' => '__return_null',
    115                 'args'     => array(
     115                'methods'             => array( 'GET' ),
     116                'callback'            => '__return_null',
     117                'permission_callback' => '__return_true',
     118                'args'                => array(
    116119                    'foo' => array(),
    117120                ),
     
    132135            '/test',
    133136            array(
    134                 'methods'  => array( 'GET' ),
    135                 'callback' => '__return_null',
    136                 'args'     => array(
     137                'methods'             => array( 'GET' ),
     138                'callback'            => '__return_null',
     139                'permission_callback' => '__return_true',
     140                'args'                => array(
    137141                    'foo' => array(
    138142                        'default' => 'bar',
     
    151155            '/test',
    152156            array(
    153                 'methods'  => array( 'GET' ),
    154                 'callback' => '__return_true',
     157                'methods'             => array( 'GET' ),
     158                'callback'            => '__return_true',
     159                'permission_callback' => '__return_true',
    155160            )
    156161        );
     
    172177            array(
    173178                array(
    174                     'methods'  => array( 'HEAD' ),
    175                     'callback' => '__return_true',
     179                    'methods'             => array( 'HEAD' ),
     180                    'callback'            => '__return_true',
     181                    'permission_callback' => '__return_true',
    176182                ),
    177183                array(
     
    194200            array(
    195201                array(
    196                     'methods'  => WP_REST_Server::READABLE,
    197                     'callback' => '__return_false',
    198                     'args'     => array(
     202                    'methods'             => WP_REST_Server::READABLE,
     203                    'callback'            => '__return_false',
     204                    'permission_callback' => '__return_true',
     205                    'args'                => array(
    199206                        'data' => array(),
    200207                    ),
     
    267274            '/test',
    268275            array(
    269                 'methods'      => 'GET',
    270                 'callback'     => '__return_null',
    271                 'should_exist' => false,
     276                'methods'             => 'GET',
     277                'callback'            => '__return_null',
     278                'permission_callback' => '__return_true',
     279                'should_exist'        => false,
    272280            )
    273281        );
     
    294302            '/test',
    295303            array(
    296                 'methods'      => 'GET',
    297                 'callback'     => '__return_null',
    298                 'should_exist' => false,
     304                'methods'             => 'GET',
     305                'callback'            => '__return_null',
     306                'permission_callback' => '__return_true',
     307                'should_exist'        => false,
    299308            )
    300309        );
     
    304313            '/test',
    305314            array(
    306                 'methods'      => 'POST',
    307                 'callback'     => '__return_null',
    308                 'should_exist' => false,
     315                'methods'             => 'POST',
     316                'callback'            => '__return_null',
     317                'permission_callback' => '__return_true',
     318                'should_exist'        => false,
    309319            )
    310320        );
     
    343353            '/test',
    344354            array(
    345                 'methods'      => 'POST',
    346                 'callback'     => '__return_null',
    347                 'should_exist' => false,
     355                'methods'             => 'POST',
     356                'callback'            => '__return_null',
     357                'permission_callback' => '__return_true',
     358                'should_exist'        => false,
    348359            )
    349360        );
     
    366377            array(
    367378                array(
    368                     'methods'  => array( 'GET' ),
    369                     'callback' => '__return_null',
     379                    'methods'             => array( 'GET' ),
     380                    'callback'            => '__return_null',
     381                    'permission_callback' => '__return_true',
    370382                ),
    371383                array(
     
    13281340            '/test',
    13291341            array(
    1330                 'methods'  => array( 'GET' ),
    1331                 'callback' => '__return_null',
    1332                 'args'     => array(
     1342                'methods'             => array( 'GET' ),
     1343                'callback'            => '__return_null',
     1344                'permission_callback' => '__return_true',
     1345                'args'                => array(
    13331346                    'someinteger' => array(
    13341347                        'validate_callback' => array( $this, '_validate_as_integer_123' ),
     
    13631376            '/test',
    13641377            array(
    1365                 'methods'  => array( 'GET' ),
    1366                 'callback' => function () {
     1378                'methods'             => array( 'GET' ),
     1379                'callback'            => function () {
    13671380                    return new WP_REST_Response();
    13681381                },
     1382                'permission_callback' => '__return_true',
    13691383            )
    13701384        );
     
    13841398            '/test',
    13851399            array(
    1386                 'methods'  => array( 'GET' ),
    1387                 'callback' => function () {
     1400                'methods'             => array( 'GET' ),
     1401                'callback'            => function () {
    13881402                    return new WP_REST_Response( 'data', 204 );
    13891403                },
     1404                'permission_callback' => '__return_true',
    13901405            )
    13911406        );
     
    14741489            '/test',
    14751490            array(
    1476                 'methods'  => array( 'GET' ),
    1477                 'callback' => function() {
     1491                'methods'             => array( 'GET' ),
     1492                'callback'            => function() {
    14781493                    return new WP_REST_Response( 'data', 204 );
    14791494                },
     1495                'permission_callback' => '__return_true',
    14801496            )
    14811497        );
     
    14841500            '/test',
    14851501            array(
    1486                 'methods'  => array( 'GET' ),
    1487                 'callback' => function() {
     1502                'methods'             => array( 'GET' ),
     1503                'callback'            => function() {
    14881504                    return new WP_REST_Response( 'data', 204 );
    14891505                },
     1506                'permission_callback' => '__return_true',
    14901507            )
    14911508        );
Note: See TracChangeset for help on using the changeset viewer.