skip to content
Back to GitHub.com
Home Bounties Research Advisories CodeQL Wall of Fame Get Involved Events
October 25, 2023

GHSL-2023-141: SQL injection in Nocodb - CVE-2023-43794

Sylwia Budzynska

Coordinated Disclosure Timeline

Summary

Nocodb contains SQL injection vulnerability, that allows an authenticated attacker with creator access to query the underlying database.

Product

nocodb/nocodb

Tested Version

0.109.2

Details

SQL injection in SqliteClient.ts (GHSL-2023-141)

By supplying a specially crafted payload to the given below parameter and endpoint, an attacker can inject arbitrary SQL queries to be executed. Since this is a blind SQL injections, an attacker may need to use time-based payloads which would include a function to delay execution for a given number of seconds. The response time indicates, whether the result of the query execution was true or false. Depending on the result, the HTTP response will be returned after a given number of seconds, indicating TRUE, or immediately, indicating FALSE. In that way, an attacker can reveal the data present in the database.

The triggerList method creates a SQL query using the user-controlled table_name parameter value from the tableCreate endpoint.

async triggerList(args: any = {}) {
  const _func = this.triggerList.name;
  const result = new Result();
  log.api(`${_func}:args:`, args);

  try {
    args.databaseName = this.connectionConfig.connection.database;

    const response = await this.sqlClient.raw(
      `select *, name as trigger_name from sqlite_master where type = 'trigger' and tbl_name='${args.tn}';`,
    );
[...]

This issue was found with the CodeQL query SQL query built from user-controlled sources.

Proof of concept

This proof of concept requires creator-level access.

Use an HTTP proxy, such as Burp Suite, to be able to capture projectId and baseId values.

  1. In Nocodb, Create a new database and a table. That action triggers a POST request to /api/v1/db/meta/projects/:projectId/:baseId/tables.
  2. Copy the POST request with valid cookies and projectId and baseId values to/api/v1/db/meta/projects/:projectId/:baseId/tables.
  3. Change the value of the table_name value to foo' OR UPPER(HEX(RANDOMBLOB(100000000/2))) -- /**/ and send the request.

The payload will cause the database to wait around 30 seconds, depending on the hardware the database is running on, indicating the payload is executed.

For more information about testing applications for SQL injection see OWASP Web Security Testing Guide - Testing for SQL injection.

Impact

This issue may lead to Information Disclosure.

CVE

Credit

This issue was discovered and reported by GHSL team member @sylwia-budzynska (Sylwia Budzynska).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2023-141 in any communication regarding this issue.