n8n-io/n8n · error · SecurityViolationError
Security violations detected
Error message
Security violations detected
What it means
Thrown by TaskAnalyzer.validate when the AST-based static security scan of Python user code detects one or more security violations. The SecurityValidator walks the parsed AST and collects violation descriptions; if any are found, they are joined with newlines and passed as the description of a SecurityViolationError. This is a pre-execution static analysis pass that catches dangerous patterns before the code runs in the subprocess.
Source
Thrown at packages/@n8n/task-runner-python/src/task_analyzer.py:363
self._cache.move_to_end(cache_key)
if len(cached_violations) == 0:
return
self._raise_security_error(cached_violations)
tree = ast.parse(code)
security_validator = SecurityValidator(self._security_config)
security_validator.visit(tree)
self._set_in_cache(cache_key, security_validator.violations)
if security_validator.violations:
self._raise_security_error(security_validator.violations)
def _raise_security_error(self, violations: CachedViolations) -> None:
raise SecurityViolationError(
message="Security violations detected", description="\n".join(violations)
)
def _to_cache_key(self, code: str) -> CacheKey:
code_hash = hashlib.sha256(code.encode()).hexdigest()
return (code_hash, self._allowlists)
def _set_in_cache(self, cache_key: CacheKey, violations: CachedViolations) -> None:
if len(self._cache) >= MAX_VALIDATION_CACHE_SIZE:
self._cache.popitem(last=False) # FIFO
self._cache[cache_key] = violations.copy()
self._cache.move_to_end(cache_key)
View on GitHub (pinned to 5ac6606e81)
Solutions
- Read the SecurityViolationError description to see which specific patterns were flagged.
- Remove or replace dangerous constructs: use direct imports instead of __import__, avoid eval/exec.
- If the flagged construct is legitimate, refactor to an explicitly allowed alternative.
- Adjust the security allowlist if the code is trusted and the pattern is a false positive (consult your security policy first).
Example fix
# before — flagged by analyzer
import os
os.system('rm -rf /tmp/test')
getattr(os, 'sys' + 'tem')('whoami')
# after — use allowed APIs
# Use the HTTP Request node or an allowed module instead
import json
result = json.dumps({'key': 'value'}) Defensive patterns
Strategy: validation
Validate before calling
import ast
def pre_validate_code(code: str) -> list[str]:
"""Check for obvious security violations before submission."""
violations = []
tree = ast.parse(code)
for node in ast.walk(tree):
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Name) and node.func.id in ('eval', 'exec', 'compile'):
violations.append(f'Use of {node.func.id}() is not allowed')
if isinstance(node, ast.Attribute) and node.attr.startswith('_'):
violations.append(f'Access to {node.attr} is not allowed')
return violations
issues = pre_validate_code(user_code)
if issues:
raise ValueError('Security issues: ' + '; '.join(issues)) Try / catch
from task_analyzer import TaskAnalyzer
from _sandbox_callables import SecurityViolationError
try:
analyzer.validate(code)
except SecurityViolationError as e:
print(f'Security violations: {e.description}')
# show violations to user for correction Prevention
- Avoid using eval(), exec(), compile(), or __import__() in Code Node Python.
- Don't access dunder attributes (__class__, __mro__, __subclasses__) in user code.
- Pre-validate user code with a local AST check before submitting to the runner.
- Educate users on sandbox restrictions and supported APIs.
When it happens
Trigger: Python Code Node code is submitted for execution. TaskAnalyzer.validate parses it into an AST, runs SecurityValidator.visit(tree), and the validator flags constructs like dangerous attribute access, use of eval/exec, access to dunder attributes, or calls to forbidden functions. The violations list is non-empty, triggering _raise_security_error.
Common situations: User code accesses __import__, __builtins__, or other dunder attributes to bypass sandboxing. Code uses eval(), exec(), compile(), or getattr for dynamic attribute access on sensitive objects. AST patterns matching known escape vectors from the sandbox. The allowlist is restrictive and the code uses introspection or metaprogramming.
Related errors
- String pattern accessing '{attr}' is disallowed, because it
- Security violation detected
- Module '${moduleName}' is disallowed
- Wildcard '*' in {list_name} must be used alone, not with oth
- read-only
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/1cdb0a04d9e975cb.
Report an issue: GitHub.