Restrict Jinja environment_params path imports to an allowlist (CVE-2026-29514)#22078
Restrict Jinja environment_params path imports to an allowlist (CVE-2026-29514)#22078Chocapikk wants to merge 1 commit into
Conversation
…026-29514) RenderTemplateMixin.get_environment_params() resolved any dotted path passed in environment_params['undefined'] or environment_params['finalize'] via import_string(). Any authenticated user with extras.add_exporttemplate (or extras.add_configtemplate + extras.render_configtemplate) could pass 'finalize: subprocess.getoutput' and execute arbitrary shell commands as the NetBox service user when the template was rendered. Tracked as CVE-2026-29514 (CVSS 8.8 High, CWE-94). The path-import behavior was introduced in 063d1fe (PR netbox-community#19962) on 2025-07-29 and has been unchanged since. Fix: - Add JINJA_ENV_PARAM_IMPORT_ALLOWLIST in extras/constants.py listing the dotted paths that may be resolved for each path-import key. - 'undefined': the four jinja2 undefined classes only. - 'finalize': empty by default, no arbitrary callable can be imported. - RenderTemplateMixin.clean() rejects unsafe values at save time. - RenderTemplateMixin.get_environment_params() re-validates at render time (defense in depth) and works on a copy of environment_params so the stored value is never mutated. Tests cover the allowlisted path resolving, the disallowed values being rejected at clean() and at render time, and unrelated parameters (trim_blocks, lstrip_blocks) being unaffected. Signed-off-by: Chocapikk <balgogan@protonmail.com>
|
Thank you for your interest in contributing to NetBox, however it appears there is no accepted issue that correlates to this pull request. Before pull requests are opened, we require an accepted issue as per our contributing guide. Please first open an issue and wait for it to be accepted before further work is done on this pull request. |
|
Hi @jeremystretch, Apologies for skipping that step. Context: this is a security fix (CVE-2026-29514) originally reported to I just opened an issue: #22079 Happy to wait for it to be triaged before any further work on this PR. Let me know if you'd like me to adjust anything. Thanks for the quick review. |
Fix: restrict Jinja
environment_paramspath imports to an allowlist (CVE-2026-29514)What this fixes
RenderTemplateMixin.get_environment_params()resolves theundefinedandfinalizekeys via Django'simport_string()with no restriction. Any authenticated user withextras.add_exporttemplate(orextras.add_configtemplate+extras.render_configtemplate) can passfinalize: "subprocess.getoutput"and execute arbitrary shell commands as the NetBox service user when the template is rendered.Tracked as CVE-2026-29514 (CVSS 8.8 High, CWE-94).
Where the bug came from
The path-import behavior was introduced in 063d1fe (#19962, "Closes #18797: Support path import for certain Jinja environment parameters", 2025-07-29) and has been unchanged since. v4.5.4 and current
mainare byte-identical fornetbox/extras/models/mixins.py.Fix
JINJA_ENV_PARAM_IMPORT_ALLOWLISTinextras/constants.pymapping each path-import key to the set of dotted paths that may be resolved:undefined: the four Jinja2 undefined classes (Undefined,ChainableUndefined,DebugUndefined,StrictUndefined).finalize: empty by default. No arbitrary callable can be imported.RenderTemplateMixin.clean()now rejects unsafe values at save time.RenderTemplateMixin.get_environment_params()re-validates at render time (defense in depth) and works on a copy ofenvironment_paramsso the stored value is never mutated.Tests
extras.tests.test_models.JinjaEnvironmentParamsTestcovers:undefinedvalue resolves correctly,undefinedvalue is rejected,finalize: subprocess.getoutputpayload is rejected atclean(),get_environment_params()rejects unsafe values even whenclean()was bypassed,trim_blocks,lstrip_blocks) are unaffected.References