VAITP Dataset

← Back to the dataset

CVE-2026-56777

n8n Python Code node AST bypass can lead to environment variable disclosure.

  • CVSS 5.3
  • CWE-184
  • Input Validation and Sanitization
  • Remote

n8n before 2.25.7 and 2.26.x before 2.26.2 contains an abstract syntax tree (AST) security validator bypass in the Python Code node. An authenticated user with permission to create or modify workflows containing a Python Code node can bypass the validator and access the task executor module namespace. The issue only affects self-hosted instances where the Python Task Runner is enabled; where N8N_BLOCK_RUNNER_ENV_ACCESS is configured to allow it, this can disclose environment variables accessible to the task runner process.

CVSS base score
5.3
Published
2026-06-30
OWASP
A03 Injection
Orthogonal defect classification
Checking
Code defect classification
Incorrect Check
Category
Input Validation and Sanitization
Subcategory
Insecure Parsing or Deserialization
Accessibility scope
Remote
Impact
Information Disclosure
Affected component
n8n

Solution

Upgrade to n8n version 2.25.7, 2.26.2, or later.

Vulnerable code sample

def bypass_validator(leaked_data=__import__("os").environ):
    # A naive AST validator might only check the function body for
    # disallowed calls or imports, missing this default argument
    # which is evaluated at function definition time.
    return {"leaked_env": dict(leaked_data)}

# The n8n Python Code node would typically return the result of the last expression.
# Calling the function makes it return the captured environment variables.
bypass_validator()

Patched code sample

As CVE-2026-56777 is a fictional vulnerability identifier, the actual code fix from n8n's repository does not exist. However, the description points to a bypass in an Abstract Syntax Tree (AST) validator. A fix would involve strengthening this validator.

The following Python code represents a plausible fix. It implements a more robust AST validator that recursively checks for forbidden attribute names and function calls, which are common vectors for sandbox escapes, thereby preventing access to the underlying execution environment as described in the CVE.

```python
import ast

# A set of attribute names commonly used in sandbox escape techniques.
# The vulnerability likely stemmed from an incomplete list or a check
# that could be bypassed. This strengthened list is part of the fix.
FORBIDDEN_ATTRIBUTES = {
    '__globals__',      # Accesses a function's global namespace.
    '__builtins__',     # Provides access to all built-in identifiers.
    '__subclasses__',   # Lists all classes, allowing access to dangerous ones.
    '__import__',       # The built-in import function.
    '__init__',         # Can be used to find the class and its globals.
    '__closure__',      # Can expose variables from an outer scope.
    '__code__',         # Contains the compiled bytecode of a function.
    '__bases__',        # Provides access to the base classes of a class.
    'environ',          # Directly references environment variables, e.g., on `os`.
    'system',           # A common dangerous function on the `os` module.
}

# A set of built-in functions that are too dangerous to allow in a sandbox.
FORBIDDEN_BUILTINS = {
    'eval',
    'exec',
    'open',
    '__import__',
}


class SecureAstValidator(ast.NodeVisitor):
    """
    Represents the fixed AST validator. It traverses the AST of user-provided
    code and raises a PermissionError if it encounters patterns that could
    lead to a sandbox escape.
    """

    def visit_Attribute(self, node: ast.Attribute):
        """
        The core of the fix. This method unconditionally blocks access to any
        attribute name present in the FORBIDDEN_ATTRIBUTES set. The previous
        vulnerable implementation likely missed this comprehensive check.
        """
        if node.attr in FORBIDDEN_ATTRIBUTES:
            raise PermissionError(
                f"Access to the restricted attribute '{node.attr}' is forbidden."
            )
        # Continue traversing the tree to check for nested attributes.
        self.generic_visit(node)

    def visit_Call(self, node: ast.Call):
        """
        Strengthens security by preventing calls to dangerous built-in functions.
        This complements the attribute check.
        """
        if isinstance(node.func, ast.Name) and node.func.id in FORBIDDEN_BUILTINS:
            raise PermissionError(
                f"Calling the restricted built-in function '{node.func.id}()' is forbidden."
            )
        self.generic_visit(node)


def validate_user_code_securely(code_string: str):
    """
    This function represents the secure entry point for running user code.
    It parses the code into an AST and uses the fixed SecureAstValidator
    to check for vulnerabilities before execution.
    
    Args:
        code_string: The Python code provided by the user.

    Raises:
        PermissionError: If the code contains forbidden patterns.
        SyntaxError: If the code is not valid Python.
    """
    # 1. Parse the user's code into an Abstract Syntax Tree.
    tree = ast.parse(code_string)
    
    # 2. Instantiate and run the strengthened validator.
    validator = SecureAstValidator()
    validator.visit(tree)
    
    # 3. If the validator completes without raising an error, the code is
    #    considered safe to proceed to the next stage (e.g., execution).

Payload

return [{'json': dict(task_executor.os.environ)}]

Cite this entry

@misc{vaitp:cve202656777,
  title        = {{n8n Python Code node AST bypass can lead to environment variable disclosure.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-56777},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-56777/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::