Varonis Threat Labs found a SQL injection vulnerability and a logical access flaw in Zendesk Explore, the reporting and analytics service in the popular customer service solution, Zendesk.
There is no evidence that any Zendesk Explore customer accounts were exploited, and Zendesk started working on a fix the same day it was reported. The company fixed multiple bugs in less than one workweek with zero customer action required.
Before it was patched, the flaw would have allowed threat actors to access conversations, email addresses, tickets, comments, and other information from Zendesk accounts with Explore enabled.
"Zendesk started working on a fix the same day it was reported. The company fixed multiple bugs in less than one workweek with zero customer action required."
To exploit the vulnerability, an attacker would first register for the ticketing service of its victim's Zendesk account as a new external user. Registration is enabled by default because many Zendesk customers rely on end-users submitting support tickets directly via the web. Zendesk Explore is not enabled by default but is heavily advertised as a requirement for the analytic insights page.
Execute, nested encodings, and XMLs, oh my!
Zendesk uses multiple GraphQL APIs in its products, especially in the administration console. Because GraphQL is a relatively new API format, we started our research there. We found one particularly interesting object type in Zendesk Explore named QueryTemplate.
The querySchema field stood out because it contains a Base64-encoded XML document named Query inside of a JSON object, and many of the attributes in the XML were Base64-encoded JSON objects themselves. Translation? That's a Base64-encoded JSON object, inside a Base64-encoded XML document, inside a JSON object. Phew!
Multiple nested encodings always catch our attention because a large number of wrappers around data usually means that many different services (which were most likely created by separate developers or even teams) are used to process this data. More code usually means more potential locations for vulnerabilities.
For this reason, we dug deeper into Zendesk Explore using the admin user of our own lab account in Zendesk. When visualizing a report in Zendesk Explore, we found an API called execute-query. This API method accepts a JSON object with the Query XML, along with multiple other XML parameters, some of which are encoded in Base64.
One of the fields passed to the API is extra_param3_value which includes a plain-text XML document, DesignSchema, not encoded in Base64. This document defines the relationship between an AWS RDS (managed relational database) and the aforementioned Query XML document.
All the name attributes in this XML document, which define the tables and columns to be queried, were found to be vulnerable to a SQL injection attack. The challenge for our team was how to exploit the SQLi vulnerability to exfiltrate data.
The XML parsing engine on the back end was willing to accept single-quoted attributes instead of the default double-quoted attributes, allowing us to escape the double-quotes in the table name.
Now we needed a way to write strings in the query without using single quotes or double quotes. Fortunately, PostgreSQL, the database used by Zendesk Explore, provides a convenient method for representing strings: dollar-quoted string constants. The characters “$$” can be used to define a string in lieu of the standard single quote character in an SQL statement.
Using this string representation method, we were able to extract the list of tables from Zendesk's RDS instance and continue to exfiltrate all the information stored in the database, including email addresses of users, leads, and deals from the CRM, live agent conversations, tickets, help center articles, and more.
The logical access flaw
SQL injections are always interesting but being able to exfiltrate data as an admin is not very exciting. We were looking for a broader impact, so we decided to study how this execute-query API really worked.
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 columns, rows, slicers, measures, and explosions of the query, as well as the visualization configuration in JSON format. The document also contains a reference to the “cubeModels” property. “cubeModels” contains an XML document named “OLAPSchema” that defines the tables that can be queried in the selected data source.
The execute-query API did not perform several logical checks on requests:
- The integrity of documents was not checked, allowing our team to modify them in ways that exposed the inner workings of the system.
- “query,” “datasources,” and “cubeModels” IDs were not evaluated to see if they belonged to the current user.
- Finally, and most critically, the API endpoint did not verify that the caller had permission to access the database and execute queries. This meant that a newly created end-user could invoke this API, change the query, and steal data from any table in the target Zendesk account's RDS, no SQLi required.
Summing it up
Varonis Threat Labs helped Zendesk solve a SQLi vulnerability and an access control flaw in Zendesk Explore that would have allowed a threat 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. No action is needed from current customers.
We've been keeping the world's most valuable data out of enemy hands since 2005 with our market-leading data security platform.How it works
Tal Peleg is a senior security researcher at Varonis. Also known as TLP, Tal is a full-stack hacker with experience in malware analysis, Windows domains, web servers, and cloud. His research is currently focused on cloud applications and APIs.