CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-JQWR-VX3P-R266

GHSA-JQWR-VX3P-R266: SQL Injection in n8n PostgresTrigger Node

Alon Barad
Alon Barad
Software Engineer

Jul 23, 2026·7 min read·2 visits

Executive Summary (TL;DR)

Authenticated n8n users can execute arbitrary SQL commands on connected PostgreSQL databases by exploiting unescaped identifier interpolation within the PostgresTrigger node.

An authenticated SQL injection vulnerability (CWE-89) in n8n's PostgresTrigger node allows users with workflow creation or modification privileges to inject arbitrary SQL statements. Because n8n dynamically constructs database administration and event subscription queries by directly interpolating user-controlled parameters—such as PostgreSQL channel, function, and trigger names—without sanitization or identifier quoting, attackers can execute arbitrary queries within the context of the configured database credentials, potentially leading to unauthorized data exposure, system tampering, or remote code execution.

Vulnerability Overview

n8n relies on node integrations to perform a wide variety of actions, with the PostgresTrigger node facilitating continuous integration with PostgreSQL environments. This node acts as an event subscriber, monitoring target tables for activity such as row insertions, modifications, or deletions, and passing those events downstream to activate active workflows. To handle these events asynchronously, n8n must programmatically configure event listeners inside the target database schema. This operation requires executing Data Definition Language (DDL) and administrative operations dynamically.

The vulnerability resides in the way these administrative queries are assembled. Under normal operations, the application creates custom stored procedures, trigger bindings, and asynchronous publication channels on the fly. Because user input is accepted to specify identifiers such as the helper function name, trigger name, or notification channel, the application exposes an attack surface to anyone authorized to construct or modify workflows.

If an attacker can manipulate these properties, they can bypass the intended query parameters and insert raw SQL commands. Because these queries run with the privileges of the connected PostgreSQL server account, a SQL injection flaw in this component can result in a significant compromise of the downstream database server.

Root Cause Analysis

The underlying issue stems from a structural constraint in standard SQL databases and query drivers. Standard parameterized queries, which replace placeholders like $1 or ? with verified literal values, only support Data Manipulation Language (DML) fields, such as strings, integers, or dates inside a WHERE or VALUES clause. Database drivers cannot accept structural SQL identifiers, such as database names, table names, function names, trigger bindings, or logical operators, as parameters.

To construct DDL queries dynamically, applications must instead build the query string programmatically. When doing so, developers must sanitize, escape, or explicitly quote all user-controlled database identifiers before concatenating them into the final SQL command template. In vulnerable versions of n8n, this safety layer was absent.

Specifically, when configuring or running the PostgresTrigger node, n8n dynamically generated statements to declare trigger functions and bind them to tables. The engine performed direct string interpolation on identifier fields like the PostgreSQL channel name, trigger function name, and trigger identifier. Because the backend trusted these inputs without applying identifier quoting mechanics, arbitrary SQL payloads were inserted directly into the query execution pipeline.

Code-Level Analysis

Below is a conceptual representation of the vulnerable code pattern contrasted with the secure implementation designed for the patch.

In the vulnerable codebase, string interpolation was performed directly inside DDL templates, ignoring the structural nature of the variables:

// Vulnerable Implementation Pattern
async function setupPostgresTrigger(client, config) {
  const functionName = config.functionName; // Unsanitised user input
  const triggerName = config.triggerName;   // Unsanitised user input
  const tableName = config.tableName;       // Schema identifier
 
  // Directly interpolating user input into structural commands
  const createFunctionQuery = `
    CREATE OR REPLACE FUNCTION ${functionName}()
    RETURNS trigger AS $$
    BEGIN
      PERFORM pg_notify('n8n_db_event', TG_TABLE_NAME);
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
  `;
 
  const createTriggerQuery = `
    CREATE TRIGGER ${triggerName}
    AFTER INSERT OR UPDATE ON ${tableName}
    FOR EACH ROW EXECUTE FUNCTION ${functionName}();
  `;
 
  await client.query(createFunctionQuery);
  await client.query(createTriggerQuery);
}

In the patched versions, the application ensures that all user-provided structural identifiers are passed through a defensive escaping function. In PostgreSQL environments, identifiers must either be wrapped in double-quotes and have internal double-quotes doubled, or be processed using specific library utilities like pg-format (such as the %I format specifier):

// Patched Implementation Pattern
import pgFormat from 'pg-format';
 
async function setupPostgresTriggerPatched(client, config) {
  // Utilising pgFormat.ident to properly escape SQL identifiers
  const escapedFunctionName = pgFormat.ident(config.functionName);
  const escapedTriggerName = pgFormat.ident(config.triggerName);
  const escapedTableName = pgFormat.ident(config.tableName);
 
  // The identifiers are safely enclosed in double-quotes, neutralising injection
  const createFunctionQuery = pgFormat(`
    CREATE OR REPLACE FUNCTION %I()
    RETURNS trigger AS $$
    BEGIN
      PERFORM pg_notify('n8n_db_event', TG_TABLE_NAME);
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
  `, config.functionName);
 
  const createTriggerQuery = pgFormat(`
    CREATE TRIGGER %I
    AFTER INSERT OR UPDATE ON %I
    FOR EACH ROW EXECUTE FUNCTION %I();
  `, config.triggerName, config.tableName, config.functionName);
 
  await client.query(createFunctionQuery);
  await client.query(createTriggerQuery);
}

This structural shift from direct string interpolation to strict identifier formatting ensures that any injected structural symbols are interpreted strictly as literal components of the identifier name, thereby neutralizing the SQL syntax breakout.

Exploitation Methodology

Exploitation of this vulnerability requires network access to the n8n application interface and a set of active, low-privilege credentials capable of creating or editing workflows. The attacker must also target a workflow that contains (or is configured to contain) a valid PostgreSQL connection.

The following diagram illustrates the lifecycle of an exploitation attempt:

To execute an attack, the adversary inputs a crafted string into the Function Name property of the PostgresTrigger node configuration. For instance, by supplying a payload containing a semicolon followed by a secondary command, the engine divides the execution block:

payload_func(); DROP TABLE application_users; --

When the workflow is saved, activated, or tested, n8n sends the command to the PostgreSQL server. The database parser interprets the input as follows:

  1. It processes the initial CREATE OR REPLACE FUNCTION payload_func()... command.

  2. It detects the semicolon, closing the initial declaration context.

  3. It treats the next sequence, DROP TABLE application_users, as a separate, subsequent statement, executing it immediately.

  4. It treats the double hyphens (--) as a comment, ignoring any leftover structural syntax from the original template.

Impact Assessment

The direct impact of successful exploitation is defined by the capabilities and permissions of the database user configured inside n8n. If the node runs with basic read and write permissions, the attacker can manipulate, delete, or exfiltrate all tables within the accessible schemas. This can compromise credential stores, transactional data, or operational parameters.

If the configured database account possesses elevated administrative privileges or is a SUPERUSER, the risk surface expands significantly. Under these conditions, an attacker can pivot from SQL execution to system-level commands on the underlying host operating system. This is frequently achieved using PostgreSQL-specific functionalities like COPY ... TO PROGRAM or administrative extensions:

-- Command execution template via COPY TO PROGRAM
COPY (SELECT 1) TO PROGRAM 'id > /tmp/out';

The CVSS v4.0 assessment registers a base score of 5.8. Although the initial impact to n8n itself is low since the host container or server environment is separate, the subsequent impact to the database infrastructure is classified as high across confidentiality, integrity, and availability.

Remediation and Defenses

The primary and recommended action is to update the n8n deployment to a patched release. Ensure your platform is aligned with one of the following official versions:

  • Version 1.123.67 or later (for 1.x installations)

  • Version 2.31.5 or later (for 2.x stable installations)

  • Version 2.32.1 or later (for 2.x latest installations)

If immediate upgrading is not possible, the PostgresTrigger node can be deactivated globally to eliminate the vulnerability's attack surface. To do this, configure the NODES_EXCLUDE environment variable in the host system configuration:

export NODES_EXCLUDE="n8n-nodes-base.postgresTrigger"

Furthermore, apply the principle of least privilege to all database connections configured in n8n. Ensure that the database users assigned to these credentials do not have SUPERUSER privileges, and explicitly restrict their abilities to create, modify, or execute procedures outside of the minimum functional scope required for the integration.

Official Patches

n8n-ioGitHub Security Advisory
n8n-iov1.123.67 Release Tag
n8n-iov2.31.5 Release Tag
n8n-iov2.32.1 Release Tag

Technical Appendix

CVSS Score
5.8/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H

Affected Systems

n8n (npm package)n8n-nodes-base module

Affected Versions Detail

Product
Affected Versions
Fixed Version
n8n
n8n-io
< 1.123.671.123.67
n8n
n8n-io
>= 2.0.0-rc.0, < 2.31.52.31.5
n8n
n8n-io
>= 2.32.0, < 2.32.12.32.1
AttributeDetail
CWE IDCWE-89
Attack VectorNetwork (Low Privileges Required)
CVSS Score5.8
Exploit StatusNone (No verified public proof of concept)
ImpactDatabase Compromise / Potential Remote Code Execution
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1505Server Software Component
Persistence
CWE-89
Improper Neutralization of Special Elements used in an SQL Command

The software constructs an SQL command using externally-influenced input, but does not neutralize or incorrectly neutralizes elements that could modify the intended SQL command.

Vulnerability Timeline

Vulnerability identified and reported by researcher sm1ee
2024-03-20
Advisory published and patches released for 1.x and 2.x branches
2024-04-10

References & Sources

  • [1]GitHub Security Advisory GHSA-jqwr-vx3p-r266
  • [2]GitHub Global Advisory Entry
  • [3]Discoverer Profile - sm1ee

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•40 minutes ago•GHSA-9CMH-XCQM-5HQR
5.8

GHSA-9cmh-xcqm-5hqr: Cross-Tenant Module-Cache Poisoning in n8n JS Task Runner

A module-cache poisoning vulnerability exists in the n8n JavaScript task runner. In multi-tenant or multi-user n8n deployments, custom code executed inside Code nodes shares a single Node.js process and memory space. If custom module loading is enabled via configuration, an authorized user can dynamically patch (monkey-patch) globally cached modules. Subsequent executions of workflows by other tenants or users that load the same module will receive the poisoned reference, resulting in cross-tenant data exposure, credential hijacking, or integrity compromise.

Alon Barad
Alon Barad
2 views•6 min read
•about 3 hours ago•GHSA-652Q-GVQ3-74QV
5.3

GHSA-652q-gvq3-74qv: SQL Injection in n8n Snowflake Node via Unparameterized Expression Interpolation

A SQL Injection vulnerability exists in the n8n Snowflake node's executeQuery operation. The vulnerability is caused by improper neutralization of expressions interpolated directly into database query strings. When raw Snowflake queries are built using untrusted external data without parameterization, an attacker can execute arbitrary SQL commands on the subsequent Snowflake database instance.

Alon Barad
Alon Barad
1 views•7 min read
•about 8 hours ago•CVE-2024-7708
7.5

CVE-2024-7708: Resource Exhaustion via HTTP Connection Buffer Leak in Eclipse Jetty

Eclipse Jetty is subject to an uncontrolled resource consumption vulnerability in its HTTP connection handling component. When processing certain HTTP request sequences, such as those invoking the Expect: 100-Continue handshake under specific network constraints, the server fails to return allocated buffers to its central pool. Over time, this leads to buffer pool exhaustion and a complete denial of service via memory starvation.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 9 hours ago•CVE-2026-65595
8.9

CVE-2026-65595: Privilege Escalation and Remote Code Execution in n8n Token Exchange Module

CVE-2026-65595 is a high-severity privilege escalation vulnerability in the Token Exchange module of the n8n visual workflow automation platform. Due to an validation omission, the system unconditionally maps all Public API scopes to session tokens exchanged through trusted Identity Providers, entirely bypassing user-specific role checks.

Alon Barad
Alon Barad
9 views•6 min read
•about 10 hours ago•CVE-2026-65597
8.2

CVE-2026-65597: DOM-based Cross-Site Scripting (XSS) in n8n HTML Preview

A critical DOM-based Cross-Site Scripting (XSS) vulnerability exists in n8n's workflow editor HTML preview component. By failing to include a sandbox attribute on the iframe used to display node execution output, n8n allowed rendered execution outputs to run arbitrary JavaScript within the same-origin context of the editor parent window. This vulnerability can be exploited by an attacker with low-privileged ('global:member') access to hijack an authenticated administrator's session and perform unauthorized API actions.

Alon Barad
Alon Barad
5 views•5 min read
•about 11 hours ago•CVE-2026-65592
8.4

CVE-2026-65592: Stored DOM-based Cross-Site Scripting via cachedResultUrl in n8n

A Stored DOM-based Cross-Site Scripting (XSS) vulnerability exists within the frontend Resource Locator component of n8n. The flaw stems from insecure usage of window.open() where the application evaluates the workflow-persisted parameter 'cachedResultUrl' without verifying its protocol scheme. Authenticated attackers with permissions to create or edit workflows can insert a 'javascript:' URI payload, leading to arbitrary code execution in the victim's browser context upon interaction.

Alon Barad
Alon Barad
7 views•5 min read