Introduction
An authenticated user with nothing more than template creation permissions in NetBox can achieve full remote code execution on the underlying server. The attack bypasses Jinja2's sandbox through a subtle but powerful gap in the template rendering pipeline. For organizations that rely on NetBox to manage their network infrastructure data, this vulnerability (CVE-2026-29514, CVSS 8.8) exposes not just the application but the database credentials, Redis secrets, and complete network topology stored within it.
NetBox is an open source infrastructure resource modeling application used across enterprise and service provider environments to document IP address allocations, rack layouts, device inventories, and cabling. DigitalOcean built it originally, and NetBox Labs and the community now maintain it. It acts as a source of truth for network automation workflows, and that central role makes any code execution vulnerability in it especially damaging.
Technical Information
The root cause of CVE-2026-29514 is how NetBox's RenderTemplateMixin.get_environment_params() method handles the finalize and undefined parameters passed to the Jinja2 SandboxedEnvironment. The method uses Django's import_string() function to resolve these parameters into Python callables at runtime, but it does so without any allowlist or validation of the import path.
Jinja2's SandboxedEnvironment restricts what template code can do by intercepting dangerous function calls inside the template evaluation sandbox. The finalize parameter sits in a special spot in that architecture. It is a callable invoked on every rendered expression as a post processing step, and that invocation happens outside the sandbox's call interception. So even though the sandbox would normally block calls to dangerous functions like subprocess.getoutput, setting that function as the finalize callable sidesteps the protection entirely.
Attack Flow
The exploitation path is straightforward:
- An attacker authenticates to NetBox with an account that holds template creation permissions (either
extras.add_exporttemplateorextras.add_configtemplate). - The attacker creates a new template object, setting the
finalizefield withinenvironment_paramstosubprocess.getoutput. - The template body contains a simple string literal that doubles as a shell command, such as
{{ "id" }}. - The attacker triggers template rendering.
- During rendering, Jinja2 evaluates the expression
"id"(a plain string), then passes it to thefinalizecallable, which is nowsubprocess.getoutput. - The string
"id"runs as a shell command, and the output comes back directly in the HTTP response body.
Two Attack Vectors
Model inheritance in NetBox's template system creates two distinct paths to exploitation:
| Attack Vector | Required Permissions | Trigger Method |
|---|---|---|
| ExportTemplate | extras.add_exporttemplate and extras.view_exporttemplate | GET request to list endpoints with export parameter |
| ConfigTemplate | extras.add_configtemplate and extras.render_configtemplate | POST request to render endpoint |
Execution Context
In Docker deployments, the NetBox service runs as uid=999 (netbox) with gid=0 (root). Successful exploitation grants command execution in a context that can reach database credentials, Redis credentials, and the full network topology data stored in NetBox. Because the command output lands straight in the HTTP response body, this is a clean and reliable path that needs no out of band exfiltration channel.
Why the Sandbox Fails
The problem is architectural. Jinja2's SandboxedEnvironment intercepts calls made within template expressions, such as {{ foo.bar() }}. But finalize is part of the environment's own rendering machinery. The engine calls it on the result of every expression, not the template code. The sandbox has no way to check whether the finalize callable is safe, because it was never built to guard against a malicious environment configuration. So the vulnerability is not a flaw in Jinja2. It is NetBox's decision to let user controlled input configure the Jinja2 environment without restriction.
During the original code review in July 2025, when this feature was introduced, a reviewer explicitly asked about validation of the import paths. The code was merged without an allowlist, which left the door open for this bypass.
Affected Systems and Versions
The vulnerability affects NetBox versions 4.3.5 through 4.5.4 inclusive. Any deployment in this version range where non staff users hold template creation or rendering permissions is vulnerable.
Both the ExportTemplate and ConfigTemplate models are affected. Docker based deployments carry extra risk because the service runs with gid=0 (root group).
Vendor Security History
The disclosure timeline raises some process concerns. Coordinated disclosure emails went to the NetBox security contact address on March 10, 2026, but those emails were reportedly lost. That communication failure forced the security researcher to open a public tracking issue on May 4, 2026, which turned a private disclosure into a public one. Together with the July 2025 code review where validation was discussed but not implemented, this points to room for improvement in both the development review process and the vulnerability intake pipeline.
References
- NVD Entry for CVE-2026-29514
- CVE-2026-29514: NetBox Jinja2 Sandbox Bypass to RCE via RenderTemplateMixin environment_params (Chocapikk)
- NetBox GitHub Issue #22079: Public Tracking Issue
- NetBox Pull Request #22078: Restrict Jinja environment_params path imports to an allowlist
- VulnCheck Advisory: NetBox RCE via RenderTemplateMixin
- GitHub Advisory Database: GHSA-f249-4qx6-hg68



