n8n-io/n8n · error · SecurityViolationError

Security violation detected

Error message

Security violation detected

What it means

Thrown by the Python task runner's _GuardedImport wrapper when an import call targets a module not present in the security allowlist. The wrapper intercepts __import__ and importlib.import_module calls, validates the module name against the configured stdlib and external allowlists, and raises SecurityViolationError if the import is denied. Transitive imports from trusted packages may skip validation if allow_transitive_imports is enabled.

Source

Thrown at packages/@n8n/task-runner-python/src/_sandbox_callables.py:263

        object.__setattr__(self, "_original", original)
        object.__setattr__(self, "_trust_eligible", trust_eligible)

    def __call__(self, name, *args, **kwargs):
        config = object.__getattribute__(self, "_security_config")
        # When trusted, package-initiated imports skip the allowlist; user
        # imports are always validated. Applies to all package code.
        trusted = (
            object.__getattribute__(self, "_trust_eligible")
            and config.allow_transitive_imports
            and not _import_initiated_by_user_code()
        )
        if not trusted:
            validate = object.__getattribute__(self, "_validate_import")
            check_name, package = _validation_target(name, args, kwargs)
            is_allowed, error_msg = validate(check_name, config, package)
            if not is_allowed:
                assert error_msg is not None
                raise SecurityViolationError(
                    message="Security violation detected",
                    description=error_msg,
                )
        original = object.__getattribute__(self, "_original")
        return original(name, *args, **kwargs)

    def __repr__(self) -> str:
        return "<built-in function __import__>"


class _SafeFormat(_HardenedCallable):
    """Hardened wrapper around the format-validation entry point injected into
    user globals under ``EXECUTOR_SAFE_FORMAT_KEY``.

    The actual implementation lives in a module with sensitive globals, so it
    is held on a denied slot and only ever invoked through ``__call__`` — user
    code that reaches this instance cannot read it back out.
    """

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Add the module to the Python runner allowlist via the appropriate environment variable (PYTHON_FUNCTION_ALLOW_EXTERNAL or equivalent config).
  2. Enable allow_transitive_imports if a trusted package's internal imports are being blocked.
  3. Refactor to use an allowed alternative module or the n8n HTTP Request node instead of importing directly.
  4. Check the exact error_msg in the SecurityViolationError description to see which module was denied.

Example fix

# before — Python user code
import socket  # blocked if not in allowlist

# after — add to env config
# Set: PYTHON_FUNCTION_ALLOW_EXTERNAL=socket
# Then: import socket  # now allowed
Defensive patterns

Strategy: validation

Validate before calling

# Check if a module is in the allowlist before importing
import os

ALLOWLIST = set(os.environ.get('PYTHON_FUNCTION_ALLOW_EXTERNAL', '').split(','))

def is_import_allowed(module_name: str) -> bool:
    return '*' in ALLOWLIST or module_name in ALLOWLIST

if not is_import_allowed('socket'):
    raise ValueError('socket is not in the allowlist')

Try / catch

from _sandbox_callables import SecurityViolationError

try:
    import socket
except SecurityViolationError:
    # handle gracefully — use HTTP Request node or allowed alternative
    pass

Prevention

When it happens

Trigger: Python user code calls import os, import socket, or importlib.import_module('subprocess') for a module not in the configured allowlist. The _validation_target function resolves the import name, the validate function checks it against the security config's allowlists, and is_allowed returns False with an error message.

Common situations: Python Code Node attempts to import a standard library module (os, socket, subprocess) not whitelisted. Importing a third-party package (e.g. requests) that the administrator hasn't added to the external allowlist. An allowed package internally imports a denied dependency when allow_transitive_imports is False.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/cf881ab582ed6ea3. Report an issue: GitHub.