A high-severity authorization bypass vulnerability in MariaDB Server allowed authenticated users with basic SELECT permissions to read sensitive operating system files and write arbitrary documents to the database host filesystem. Documented in coordinated public disclosure via HackerOne (Report #3836021) by security researcher duongtt, the flaw resides in the CONNECT storage engine's companion User-Defined Functions (UDFs), which omitted both global FILE privilege verification and --secure-file-priv path containment checks.
| Specification Parameter | Vulnerability Detail & Telemetry | Technical Risk & Exploit Impact |
|---|---|---|
| Target Component | MariaDB CONNECT Storage Engine File UDFs (storage/connect/jsonudf.cpp & bsonudf.cpp) |
Companion UDFs providing JSON and BSON file I/O operations. |
| Vulnerability Identifier | MARIADB-2026-CONNECT-FILE-BYPASS / CWE-285 & CWE-732 |
Bypasses FILE privilege and directory confinement (secure_file_priv). |
| Severity Rating | High (CVSS 7.7) — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
Arbitrary host file read and write as the mysql operating system user. |
| Vulnerable Functions | json_file(), bson_file(), jfile_make(), bfile_make(), jbin_file() |
Available to any authenticated user with standard SQL execution rights. |
| Reporter Attribution | Security Researcher duongtt |
Disclosed via HackerOne bug bounty program; verified on MariaDB 12.3.2 GA and 13.0.1. |
The CONNECT Engine & MariaDB's File Security Model
In standard MariaDB deployments, file system interactions from SQL are governed by strict security boundaries:
- The FILE Privilege: Users must explicitly hold the global
FILEadministrative grant to invoke functions likeLOAD_FILE()or executeSELECT ... INTO OUTFILE. - The secure_file_priv Constraint: Servers are typically configured with
--secure-file-priv=/path(or an explicit directory like/tmp), strictly confining file reads and writes to that single directory path. Any attempt to access files outside this path—even by an administrator with fullFILEprivilege—is rejected by the server kernel.
The CONNECT storage engine extends MariaDB's capabilities by allowing tables to interface directly with external data formats, including CSV, XML, INI, JSON, and BSON. To streamline JSON document handling, the CONNECT engine automatically provides a collection of companion SQL functions: json_file, bson_file, jfile_make, bfile_make, and jbin_file.
Root Cause: Disconnected Authorization Gates
The security vulnerability stemmed from an implementation gap between CONNECT's table handler and its function entry points:
| Subsystem Path | Source Location | secure_file_priv Check | FILE Privilege Enforcement |
|---|---|---|---|
| CONNECT Table Handler | storage/connect/ha_connect.cc:4538, 4557 |
ENFORCED: Calls is_secure_file_path(path) |
ENFORCED: Calls check_global_access(thd, FILE_ACL) |
| CONNECT File UDFs | storage/connect/jsonudf.cpp:1587, 1636 |
MISSING: Zero path validation! | MISSING: Zero user privilege check! |
While the table creation path in ha_connect.cc carefully verified both boundaries, the standalone UDF entry points inside jsonudf.cpp (GetFileLength, GetJsonFile) opened target paths directly using standard C runtime file descriptors, completely ignoring both the caller's privileges and the global secure_file_priv setting!
Step-by-Step Proof of Concept & Attack Mechanics
To demonstrate the flaw, researcher duongtt configured a MariaDB 12.3.2 server with --secure-file-priv=/tmp. A low-privilege user named plain was created with only basic SELECT permissions on an application schema, holding zero administrative or file grants.
Step 1: Standard Protection Verification
When the user attempts to read server files using native MariaDB SQL functions, the server blocks both requests as expected:
-- Attempting to read inside secure_file_priv without FILE privilege:
SELECT LOAD_FILE('/tmp/secret.json');
-- Returns NULL: User 'plain' does not hold the FILE privilege
-- Attempting to read outside secure_file_priv:
SELECT LOAD_FILE('/etc/passwd');
-- Returns NULL: Path is outside secure_file_priv directory
Step 2: Arbitrary File Read via CONNECT UDF
The unprivileged user then invokes the CONNECT engine's json_file() function, targeting system configuration files outside secure_file_priv:
SELECT json_file('/etc/passwd');
The query succeeds immediately, returning the full contents of /etc/passwd:
+-----------------------------------------------------------------------------------+
| json_file('/etc/passwd') |
+-----------------------------------------------------------------------------------+
| root:x:0:0:root:/root:/bin/bash |
| daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin |
| mysql:x:107:113:MySQL Server,,,:/nonexistent:/bin/false |
| ... |
+-----------------------------------------------------------------------------------+
Because the function returns the raw buffer, an attacker can extract sensitive system files, including:
- Database server configuration files:
/etc/mysql/my.cnf(revealing internal replica passwords). - Database master encryption keys:
/var/lib/mysql/keyfile. - Server TLS certificates & private keys:
/etc/ssl/private/server-key.pem.
Step 3: Arbitrary File Write as mysql OS User
Even more critically, the companion function jfile_make() allowed writing arbitrary files to the filesystem under the permissions of the mysql operating system user:
SELECT jfile_make('{"backdoor":"installed","role":"admin"}',
'/var/lib/mysql/connect_udf_written.json', 0);
The server creates the file on disk outside the designated /tmp directory, owned by mysql:mysql with write permissions, giving attackers a powerful staging mechanism to drop binary libraries or overwrite database configuration files.
Enterprise Impact: Breaking Multi-Tenant Cloud Isolation
In shared hosting and multi-tenant database architectures, this vulnerability completely nullified the security boundaries established by database administrators:
- Cloud Credential Extraction: In cloud environments (AWS, GCP, Azure), database processes with access to local filesystem mounts could leak IAM instance metadata and temporary credentials.
- Co-Tenant Data Exposure: In shared databases, a tenant in database A could read raw table data files (
.ibdfiles) belonging to database B in/var/lib/mysql/database_b/.
Remediation & Upstream Fix Implementation
MariaDB patched the flaw by inserting mandatory security validation into all CONNECT UDF entry points. The patch wires check_global_access(thd, FILE_ACL) and is_secure_file_path(path) directly into the initialization routines of jsonudf.cpp and bsonudf.cpp.
Organizations unable to upgrade immediately can mitigate the risk by explicitly dropping the vulnerable CONNECT companion functions:
DROP FUNCTION IF EXISTS json_file;
DROP FUNCTION IF EXISTS bson_file;
DROP FUNCTION IF EXISTS jfile_make;
DROP FUNCTION IF EXISTS bfile_make;
DROP FUNCTION IF EXISTS jbin_file;



