Overview
CVE-2026-38428 describes Kestra v1.3.3 and earlier as vulnerable to SQL injection due to user-supplied input from a GET parameter being directly concatenated into an SQL query without sanitization or parameterization. While Kestra is a Java-based project, the underlying vulnerability pattern-untrusted input ending up in a SQL string-maps directly to Node.js/Express apps where req.query, req.params, or req.body values are interpolated into SQL. In real-world Node.js/Express deployments, this class of vulnerability can enable attackers to alter query semantics, exfiltrate data, or execute additional SQL commands depending on database permissions. This guide uses that CVE as the starting point to explain how injection surfaces appear in Node.js/Express and how to remediate them in practice.
In a typical Express route, developers may build queries by concatenating user-controlled input into SQL strings, such as a search or filter endpoint. An attacker can craft a URL like /search?q='; DROP TABLE users; -- which, if concatenated directly into a query, changes its meaning and can lead to data leakage or destructive operations. The risk is amplified when GET parameters, path params, or body fields are allowed to influence the query logic without proper parameterization. This guidance demonstrates concrete Node.js/Express patterns and how to transform them into safe, parameterized patterns that prevent injection regardless of the input content.
To fix these vulnerabilities in Node.js/Express, adopt strict parameterization for all SQL interactions, validate and whitelist inputs, and prefer query builders or ORMs that enforce parameter binding. Replace string interpolation or concatenation with prepared statements, and ensure all routes that touch the database use placeholders or named parameters. Additionally, implement automated tests to catch regression vulnerabilities and integrate static/dynamic analysis or runtime security tooling that flags non-parameterized SQL usage in route handlers.
Affected Versions
Kestra v1.3.3 and earlier
Code Fix Example
Node.js (Express) API Security Remediation
/* Vulnerable vs Fixed: Node.js/Express with MySQL (mysql2/promise) */
const express = require('express');
const mysql = require('mysql2/promise');
const app = express();
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
});
app.get('/search', async (req, res) => {
const q = req.query.q || '';
// Vulnerable pattern: string interpolation with user input
const vulnerableSql = `SELECT id, name FROM products WHERE name LIKE '%${q}%'`;
let vulnerableRows;
try {
const [rows] = await pool.query(vulnerableSql);
vulnerableRows = rows;
} catch (e) {
vulnerableRows = { error: e.message };
}
// Fixed pattern: parameterized query using placeholders
const safeSql = 'SELECT id, name FROM products WHERE name LIKE ?';
let safeRows;
try {
const [rows] = await pool.execute(safeSql, [`%${q}%`]);
safeRows = rows;
} catch (e) {
safeRows = { error: e.message };
}
res.json({ vulnerable: vulnerableRows, safe: safeRows });
});
app.listen(process.env.PORT || 3000, () => {
console.log('Server listening');
});