Apache Lucene Injection on Auth0 Integration

Apache Lucene Injection was discovered on a past assessment this year and I learned that this vulnerability wasn't mentioned much online. The reason for this is probably because Lucene Injection is limited compared to SQL Injection. Lucene Injection can only be used to query the data (index) that the application is expected to query. This can be exploited if the index (equivalent to an SQL table) is sensitive and you're only supposed to see a subset of the index or certain fields.

Application Background

The application is a multi-tenant system that stores user information for all tenants in Auth0. Reading online, Auth0 uses Lucene to query user information. The application web server called Auth0 to query users assigned to the current tenant to share cyber security incident cases with other users. This API is only supposed to query users under the tenant the user is assigned to but the user input wasn't being handled properly and allowed Lucene Injection.

Exploiting Lucene Injection

The application returned error information that disclosed the Lucene query, which made it easier to exploit. The screenshot below shows the query that expects to return only users for one tenant.

Lucene query disclosed

The following screenshots demonstrate modifying the Lucene query to return other tenant users and a boolean-based condition to discover other fields on the user index in Auth0. For the latter, an empty JSON array would be returned if the field didn't exist.

Lucene Injection to query all tenant users
Lucene Injection to discover other fields on the user index

The following payloads were used to query all tenant users and other fields in Auth0.

  // Break out of query and query all users using the name field
  1)+OR+(name:*)+OR+(name:*

  // Perform a boolean-based condition checking if the user_metadata.country field exists
  1)+OR+(name:*)+AND+(_exists_:user_metadata.country

  // Discover values searching one character at a time
  1)+OR+(name:*)+AND+(user_metadata.country:C*
  1)+OR+(name:*)+AND+(user_metadata.country:Ca*
  ...

The last two payloads could be used to query custom fields under app_metadata or user_metadata or to query other Auth0 fields (phone numbers, IP addresses, ...).

Remediation

Reading online, there was mention that Lucene supports prepared statements like SQL. As this was an integration with Auth0, the client likely encoded special characters before passing the user input to Auth0 to prevent the injection.