Varonis Labs discovers SQLi and accesses flaws in Zendesk
Varonis helped resolve an SQLi vulnerability and access control flaw in Zendesk Explore that allegedly allowed a malicious actor to leak data from Zendesk customer accounts with Explore enabled. Zendesk quickly resolved the issue and there is no longer this flaw in Explore. Therefore, no action is required from current customers.
There is no evidence that any Zendesk Explore customer accounts were exploited, and Zendesk began working on a fix the same day it was reported. The company fixed several bugs in less than a week of work.
Prior to being patched, the flaw would have allowed hackers to access conversations, email addresses, tickets, comments, and other information from Zendesk accounts with Explore enabled.
An attacker would first sign up for the ticketing service of their victim’s Zendesk account as a new external user to exploit the vulnerability. Registration is enabled by default because many Zendesk customers rely on end users submitting support tickets directly through the web. Zendesk Explore is not enabled by default but is strongly advertised as a requirement for the analytics information page.
Zendesk uses several GraphQL APIs in its products, particularly in the Admin Console. Because GraphQL is a relatively new API format, Varonis started its research there. He found a particularly interesting object type in Zendesk Explore called QueryTemplate.
The querySchema field stood out because it contained a Base64-encoded XML document named Query inside a JSON object, and many of the attributes in the XML were themselves Base64-encoded JSON objects. Translation? It is a Base64 encoded JSON object, inside a Base64 encoded XML document, inside a JSON object.
Multiple nested encodings always catch Varonis attention because a large number of wrappers around the data usually means that many different services are used to process that data. More code usually means more potential locations for vulnerabilities.
For this reason, Varonis dug deeper into Zendesk Explore using the administrator user of their lab account in Zendesk.
While viewing a report in Zendesk Explore, Varonis found an API called execute-query. This API method accepts a JSON object with the request XML and several other XML parameters, some of which are Base64 encoded.
One of the fields passed to the API is extra_param3_value, which includes a plain text XML document, DesignSchema, not Base64 encoded. This document defines the relationship between an AWS RDS (managed relational database) and the aforementioned query XML document.
All of the name attributes in this XML document, which define the tables and columns to be queried, were vulnerable to a SQL injection attack. The challenge for Varonis was to exploit the SQLi vulnerability to exfiltrate the data.
The XML parser on the back-end accepted single-quoted attributes instead of double-quoted attributes by default, allowing Varonis to escape double quotes in the table name.
Now Varonis needed a way to write strings into the query without using single or double quotes.
Fortunately, PostgreSQL, the database used by Zendesk Explore, provides a convenient way to represent strings: dollar-quoted string constants. The “$$” character can be used to define a string instead of the standard single quote character in an SQL statement.
Using this string representation method, Varonis was able to extract the list of tables from Zendesk’s RDS instance and continue to exfiltrate all information stored in the database. It included user email addresses, leads, CRM deals, live agent conversations, tickets, help center articles, and more.
SQL injections are always great, but being able to exfiltrate data as an administrator might be more exciting. So, as Varonis was looking for a broader impact, they decided to investigate how this query execution API works.
The execute-query API method accepts a JSON payload containing a “content” object with “query”, “cubeModels”, and “datasources” properties.
“query” contains a query XML document with the query columns, rows, segments, metrics, and explosions, and the visualization configuration in JSON format. The document also contains a reference to the “cubeModels” property. “cubeModels” includes an XML document named “OLAPSchema” that defines the tables that can be queried in the selected data source.
The query execution API failed to perform several logical checks on requests.
The documents were not checked for integrity, which allowed the Varonis team to modify them to expose the inner workings of the system.
The “query”, “datasources” and “cubeModels” IDs were not evaluated to see if they belonged to the current user.
Last but not least, the API endpoint did not verify that the caller had permission to access the database and execute queries. Therefore, a newly created end user could invoke this API, modify the query and steal data from any table in the target Zendesk account’s RDS; no SQLi is required.