[wp-trac] [WordPress Trac] #53994: REST API requests with session cookies but an invalid/missing nonce are considered authenticated for most of the request
WordPress Trac
noreply at wordpress.org
Tue Aug 24 17:29:08 UTC 2021
#53994: REST API requests with session cookies but an invalid/missing nonce are
considered authenticated for most of the request
--------------------------+-----------------------------
Reporter: mboynes | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Security | Version:
Severity: normal | Keywords:
Focuses: rest-api |
--------------------------+-----------------------------
**Note: the security team reviewed this and asked that I post a public
report as a hardening issue.**
If a REST API request has valid session cookies but does not include a
nonce, there is a significant portion of the process where the user is
considered validly authenticated and signed in until the nonce is finally
checked and the user account is nulled out. This period of the request is,
practically speaking, the entire portion of the request where a plugin or
theme would perform any operations before the REST response was sent (the
obvious exception is if the REST endpoint were a custom one created by the
theme or plugin, in which case, any code in direct service of dispatching
the response would be after the nonce was checked). Therefore, if a
request contains valid session cookies but an invalid or absent nonce,
plugins and themes will almost always treat the request as if the user
were validly authenticated, potentially voiding the purpose of the nonces.
In WordPress Core, the first place the user account is accessed is in
`\WP::init()`. After that, the init action fires, which of course, is a
common hook for plugins and themes. In addition, there is nothing stopping
a plugin or theme from accessing the user account well before
`\WP::init()`, e.g. immediately as it is loaded. In other words, a user
session is validated as early as an mu-plugin loading. Out-of-the-box,
WordPress does make some decisions based on the user's logged-in status
and capabilities, e.g. which mime types are allowed for an attachments
REST request and how widget content is processed. In fact, even the REST
API code itself decides whether or not to send nocache headers based on
the user's authentication state before the nonce is checked.
The request isn't de-authenticated again until the nonce is checked when
`\WP_REST_Server::check_authentication()` runs, which is immediately
before the response is dispatched in `\WP_REST_Server::serve_request()`.
=== Steps To Reproduce:
1. Sign into a WordPress site
2. Add the following code to your theme/plugin to confirm that you are
considered "signed in", even though you didn't provide a nonce
{{{#!php
<?php
add_action( 'init', function() { die( is_user_logged_in() ? 'You are
signed in' : 'You are not signed in' ); } );
}}}
3. Make a REST API request from the same browser, without a nonce present
=== Recommendations
My best suggestion for resolving the issue is to check the nonce as part
of the `determine_current_user` filter. However, this would require that
WordPress make some assumptions about the request and infer that it is a
REST request before that decision is officially made, since at this point,
the `REST_REQUEST` constant might not have been defined. Potentially, that
makes #42061 a pre-requisite.
=== Impact
I don't believe this to be a significant security vulnerability; after
all, the user would still have to be validly authenticated. But it is
certainly a vector for a CSRF attack, as it can potentially circumvent
nonces. As far as I can tell, nothing in WordPress core is critically
impacted out-of-the-box. The real impact I can foresee is that a plugin or
theme performs an action for authenticated users during the request chain,
and that action is exploited in a CSRF attack.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/53994>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list