CVE-2026-34612 Overview
CVE-2026-34612 is a critical SQL Injection vulnerability in Kestra, an open-source, event-driven orchestration platform. This vulnerability affects Kestra deployments prior to version 1.3.7 and specifically impacts the default docker-compose deployment configuration. The flaw exists in the /api/v1/main/flows/search endpoint, where insufficient input sanitization allows attackers to inject malicious SQL queries that can be leveraged to achieve Remote Code Execution (RCE) on the underlying host system.
The attack chain is particularly dangerous because it exploits PostgreSQL's COPY ... TO PROGRAM ... functionality, which allows the database to execute arbitrary operating system commands. Once an authenticated user visits a crafted malicious link, the injected payload is processed by the PostgreSQL backend, ultimately resulting in command execution on the host machine.
Critical Impact
Authenticated attackers can achieve full Remote Code Execution on the host system through SQL Injection, potentially leading to complete system compromise, data exfiltration, and lateral movement within the infrastructure.
Affected Products
- Kestra (default docker-compose deployment) versions prior to 1.3.7
- Kestra installations using PostgreSQL backend with H2 repository service
- Kestra deployments with exposed /api/v1/main/flows/search endpoint
Discovery Timeline
- 2026-04-03 - CVE-2026-34612 published to NVD
- 2026-04-07 - Last updated in NVD database
Technical Details for CVE-2026-34612
Vulnerability Analysis
This vulnerability stems from improper handling of user-supplied input in the label search functionality within Kestra's JDBC repository services. The flaw specifically affects how label keys are incorporated into dynamic SQL queries used for flow and execution searches.
When processing label search parameters, the application constructs JQ (JSON Query) expressions dynamically by directly concatenating user input into SQL field definitions. This direct string concatenation bypasses any parameterization, allowing attackers to break out of the intended query structure and inject arbitrary SQL commands.
The exploitation leverages PostgreSQL's powerful COPY ... TO PROGRAM command, which is designed for data export but can be abused to execute shell commands on the database server. When combined with the SQL injection point, this creates a direct pathway from a web request to arbitrary command execution on the underlying operating system.
Root Cause
The root cause is classic SQL Injection through unsafe string concatenation in the H2ExecutionRepositoryService.java and H2FlowRepositoryService.java files. The vulnerable code constructs dynamic SQL queries by directly embedding user-controlled label keys into JQ string expressions without proper parameterization or escaping.
The vulnerable pattern concatenates the user-supplied key variable directly into the SQL field definition string, allowing injection of arbitrary SQL syntax through carefully crafted label parameters.
Attack Vector
The attack exploits the network-accessible search endpoint and requires only low-privilege authentication. An attacker can craft a malicious URL containing the SQL injection payload in the label search parameters. When an authenticated user accesses this link—either by being tricked into clicking it or through automated means—the malicious SQL is executed against the PostgreSQL database.
The attack flow proceeds as follows: the crafted request reaches the /api/v1/main/flows/search endpoint, the label parameters are processed without sanitization, the injected SQL escapes the JQ string context, PostgreSQL executes the COPY ... TO PROGRAM command, and arbitrary OS commands run on the host system.
// Vulnerable code pattern (before patch)
// Source: https://github.com/kestra-io/kestra/commit/3926762795df8ad3e03924b370c51832ed3a21d3
if (labels != null) {
labels.forEach((key, value) ->
{
- Field<String> valueField = DSL.field("JQ_STRING(\"value\", '.labels[]? | select(.key == \"" + key + "\") | .value')", String.class);
+ Field<String> valueField = DSL.field("JQ_STRING(\"value\", CONCAT('.labels[]? | select(.key == \"', {0}, '\") | .value'))", String.class, DSL.val(key, String.class));
if (value == null) {
conditions.add(valueField.isNull());
} else {
Source: GitHub Commit Changes
The patch replaces direct string concatenation with parameterized queries using DSL.val() to properly escape the user-supplied key value, preventing SQL injection by treating the input as data rather than executable code.
Detection Methods for CVE-2026-34612
Indicators of Compromise
- Unusual queries to /api/v1/main/flows/search with suspicious label parameters containing SQL syntax characters (single quotes, semicolons, COPY, PROGRAM)
- PostgreSQL logs showing COPY ... TO PROGRAM commands originating from application queries
- Unexpected process spawning from the PostgreSQL service user
- Outbound network connections from the database server to unusual destinations
Detection Strategies
- Implement Web Application Firewall (WAF) rules to detect SQL injection patterns in the label search parameters
- Monitor PostgreSQL query logs for COPY ... TO PROGRAM statements that are not part of normal application behavior
- Deploy endpoint detection to identify anomalous child processes spawned by the PostgreSQL service
- Configure intrusion detection systems to alert on SQL injection payload patterns in HTTP request parameters
Monitoring Recommendations
- Enable detailed logging on the Kestra application to capture all search endpoint requests with full parameter values
- Configure PostgreSQL audit logging to track all COPY and PROGRAM related commands
- Establish baseline network behavior for database servers and alert on deviations
- Monitor system calls on hosts running PostgreSQL for unexpected command execution
How to Mitigate CVE-2026-34612
Immediate Actions Required
- Upgrade Kestra to version 1.3.7 or later immediately
- If immediate upgrade is not possible, restrict access to the /api/v1/main/flows/search endpoint using network-level controls
- Review PostgreSQL logs for any signs of exploitation
- Audit user sessions and access patterns for the period the vulnerable version was deployed
Patch Information
Kestra has released version 1.3.7 which addresses this SQL Injection vulnerability. The fix implements proper parameterized queries using DSL.val() to safely handle user-supplied label keys, preventing malicious input from being interpreted as SQL code. Organizations should upgrade to this version as soon as possible.
For detailed patch information, refer to the GitHub Security Advisory GHSA-365w-2m69-mp9x and the GitHub Release v1.3.7.
Workarounds
- Implement network segmentation to restrict access to the Kestra API from untrusted networks
- Configure PostgreSQL to run with minimal privileges and disable COPY ... TO PROGRAM if not required for legitimate operations
- Deploy a reverse proxy or WAF to filter requests containing SQL injection patterns before they reach the application
- Restrict the PostgreSQL user's operating system permissions to limit the impact of command execution
# PostgreSQL configuration to restrict COPY PROGRAM functionality
# Add to postgresql.conf to limit potential exploitation impact
# Restrict superuser commands (requires PostgreSQL restart)
# Note: This may impact legitimate backup operations
log_statement = 'all'
log_min_duration_statement = 0
# Monitor for suspicious COPY commands
# Add to pg_hba.conf to restrict database access
# hostssl kestra kestra_app 10.0.0.0/8 scram-sha-256
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

