Jul 28, 2026·6 min read·5 visits
NocoBase versions prior to 2.1.0-alpha.46 used an incomplete blacklist in checkSQL() validator, enabling privileged users to read system databases, query schema metadata, and extract PostgreSQL MD5/SCRAM password hashes.
NocoBase, an extensible low-code platform, was found to contain an information exposure vulnerability in its SQL Collection plugin. The validator designed to inspect SQL queries used an incomplete keyword-based blacklist, allowing users with administrative or collection creation privileges to bypass restrictions and execute arbitrary SELECT queries against PostgreSQL system catalogs. This flaw permits unauthenticated or privilege-escalated access to critical system files, active connection listings, and system user password hashes.
NocoBase features a core extension named @nocobase/plugin-collection-sql that permits authorized users to define SQL collections. These collections act as virtual database tables constructed from raw SQL queries. To prevent administrative users from executing destructive write operations or querying restricted database configurations, NocoBase implements a string-based validation function called checkSQL().
This validator functions on a blacklist methodology, seeking to catch and reject queries containing specific keywords or functions associated with administration, service interruption, or local file access. The attack surface resides in the REST API endpoints associated with the SQL Collection engine, which process these custom queries on behalf of the application service.
Because the underlying engine permits raw SQL execution, the checkSQL() filter represents the primary line of defense protecting the PostgreSQL database backend. Failure to isolate metadata schemas and credential stores means that any user capable of creating or editing an SQL collection can access system resources far beyond the logical sandbox of the NocoBase application layer.
The root cause of CVE-2026-52888 is an incomplete list of disallowed inputs, classified under CWE-184. The function checkSQL() in packages/plugins/@nocobase/plugin-collection-sql/src/server/utils.ts validated user-supplied SQL strings against a static array named dangerKeywords. This list blocked commands such as pg_sleep, pg_reload_conf, and generate_series, but entirely omitted critical PostgreSQL system tables.
In PostgreSQL, vital administrative metadata is kept in system catalog tables. These tables include pg_shadow (storing database user password hashes), pg_roles (storing role properties), and pg_stat_activity (storing real-time queries and sessions). Because the blacklist did not restrict queries referencing these catalogs, a standard SELECT query targeting them successfully passed the validator.
Additionally, the validation architecture parses statements using a primitive string-splitting approach. The validator evaluates only the first query segment isolated by a semicolon. This implementation assumes that the database driver prevents multi-statement execution, creating a technical gap that attackers can exploit to bypass the validation wrapper entirely.
The following code block highlights the vulnerable validator state in @nocobase/plugin-collection-sql compared to the official patch applied in commit 87c548969ce9258dd7f0d9571c9453ae10bc3fc4:
File: packages/plugins/@nocobase/plugin-collection-sql/src/server/utils.ts
@@ -22,6 +22,13 @@ export const checkSQL = (sql: string) => {
'pg_reload_conf',
'pg_sleep',
'generate_series',
+ 'pg_catalog',
+ 'pg_shadow',
+ 'pg_authid',
+ 'pg_auth_members',
+ 'pg_roles',
+ 'pg_stat_activity',
+ 'information_schema',
// MySQL
'LOAD_FILE',
@@ -33,7 +40,7 @@ export const checkSQL = (sql: string) => {
'sqlite3_load_extension',
'load_extension',
];
- sql = sql.trim().split(';').shift();
+ 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');
}The patch expands the blacklist array to block keywords linked to PostgreSQL system catalog schemas. The update also appends a fallback nullish string assignment (|| '') to prevent runtime crashes if the shift() output on split arrays returns an undefined reference.
Below is a flow diagram representing the validation process in the vulnerable application versions:
While this fix prevents simple queries against the specified system catalogs, the validation strategy remains fragile. The implementation does not evaluate structural query characteristics using a full SQL parser, which leaves the system open to alternative bypass strategies.
Exploitation of this vulnerability requires access to the SQL Collection execution endpoints, typically restricted to authenticated admin-role users. An attacker targets the /api/sqlCollection:execute resource with a crafted payload containing a query directed at a sensitive system view.
An example exploitation HTTP request to fetch user credential hashes from pg_shadow is structured as follows:
POST /api/sqlCollection:execute HTTP/1.1
Host: target-nocobase.local
Authorization: Bearer <JWT_ADMIN_TOKEN>
Content-Type: application/json
{
"values": {
"sql": "SELECT usename, passwd FROM pg_shadow"
}
}Because pg_shadow is not contained in the blacklist of unpatched versions, the backend process forwards this query to the database instance. The database replies with the admin usernames and their corresponding password hashes, which are returned to the attacker's console.
Furthermore, even in patched versions, the split-by-semicolon parser allows potential stacked queries if the database driver is configured to process multiple statements. A query such as SELECT 1; SELECT usename, passwd FROM pg_shadow; extracts SELECT 1 for validation, bypassing the keyword list while sending both queries to the engine. Additionally, standard application databases storing bcrypt user credentials (such as the users table) remain unblocked since they do not match PostgreSQL system catalogs.
The impact of CVE-2026-52888 is categorized as high for confidentiality, while integrity and availability are unaffected because the engine restricts execution to SELECT and WITH query forms. In a default configuration, NocoBase communicates with its database utilizing a high-privilege account. Consequently, administrative users can read password hashes of the underlying database instance, which may lead to systemic infrastructure compromise if passwords are reused.
Exposing the database schema via metadata exploration allows attackers to trace database relationships, identify sensitive client directories, and locate system integration tokens. If the system backend uses external databases, database user credential theft can lead to horizontal movement inside the target enterprise network.
This vulnerability showcases a scope change (S:C) under CVSS metrics. While the vulnerability occurs in the NocoBase software layer, its exploitation results in direct exposure of the underlying PostgreSQL management environment.
Organizations should transition away from blacklist-based filters for user-controlled raw SQL execution. The most immediate remediation action is updating the NocoBase platform installation to version 2.1.0-alpha.46, 2.0.62, or later. These versions contain the expanded keyword list and input checking routines.
To limit the scope of administrative queries, engineers must enforce the principle of least privilege at the database layer. The NocoBase application database user should be restricted from reading system catalogs. System administrators can execute the following SQL policies on PostgreSQL to restrict user catalog access:
-- Revoke read access to system catalogs from the application user
REVOKE SELECT ON pg_shadow FROM public;
REVOKE SELECT ON pg_authid FROM public;Furthermore, ensure that the application's PostgreSQL connection user is not configured with superuser status. Restricting connection accounts ensures that database engine permissions block read attempts on system-level tables, regardless of any application-level blacklist bypasses.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
@nocobase/plugin-collection-sql NocoBase | <= 2.0.59 | 2.1.0-alpha.46 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-184 |
| Attack Vector | Network (AV:N) |
| CVSS Base Score | 6.8 |
| EPSS Score | 0.00269 |
| Exploit Maturity | Proof-of-Concept (PoC) |
| CISA KEV Status | Not Listed |
The application filters or validates inputs using an incomplete blocklist, leaving dangerous entities open to bypasses.
CVE-2025-6120 is a critical memory corruption vulnerability in the Open Asset Import Library (Assimp) affecting versions up to and including 5.4.3. The flaw is located in the Half-Life 1 MDL file format loader, specifically within the read_meshes function in HL1MDLLoader.cpp. It arises due to a lack of verification checks on array, bone, skin, or vertex indices parsed directly from a binary stream, resulting in a heap-based buffer overflow or out-of-bounds memory access.
A local file disclosure vulnerability exists in the Rust-based package skilo. When copying files during skill installation, the application recursively traverses directories but dereferences symbolic links, resulting in unauthorized local file reading.
Pagy, an agile pagination gem for plain Ruby, contains a directory traversal vulnerability in its internationalization (I18n) module prior to version 43.5.6. An unauthenticated remote attacker can exploit this flaw by submitting path traversal sequences to the locale setter, allowing them to probe the server filesystem. The resulting behavior creates a highly reliable file existence and readability side-channel oracle for YAML files.
CVE-2026-66064 is an access control list (ACL) and blocklist bypass vulnerability in the goshs file server prior to version 2.1.5. Due to an inconsistency between uncleaned raw URI path evaluation and normalized file access, remote unauthenticated attackers can retrieve protected files, including the configuration file containing password hashes, by appending a trailing slash to the requested path.
CVE-2026-54719 is a high-severity Access Control List (ACL) authorization bypass vulnerability in goshs, a lightweight HTTPS-capable server used for file sharing. The issue allows unauthenticated network attackers to completely bypass file-level and directory-level authentication mechanisms and blocklists by requesting protected resources via the bulk ZIP-download route (?bulk). This vulnerability represents a residual flaw following a partial remediation attempt for CVE-2026-40189.
An issue in the ruby-oauth2 gem allows unauthenticated attackers to steal OAuth access tokens or perform Server-Side Request Forgery (SSRF) via a protocol-relative URI in HTTP Location redirect headers.