update_docs's translation-build step runs a shell command built via %-string-formatting into subprocess.check_call(..., shell=True):
docs/management/commands/update_docs.py:
subprocess.check_call(
"cd %s && make translations" % trans_dir, shell=True, **extra_kwargs
)
trans_dir is derived from release.version, and Release.version is a plain CharField with no format validator, so nothing at the model/admin layer restricts its contents.
It isn't exploitable in practice: only trusted release-manager staff can set Release.version, and that same group already has direct server/deploy access to the docs-build host, so there's no privilege boundary being crossed. Not treated as a security issue, but worth fixing as routine hardening, shell=True with string-formatted input is bad practice regardless of who can reach it.
Fix should be along the lines of: subprocess.check_call(["make", "translations"], cwd=trans_dir, **extra_kwargs)
update_docs's translation-build step runs a shell command built via%-string-formatting intosubprocess.check_call(..., shell=True):docs/management/commands/update_docs.py:trans_diris derived fromrelease.version, andRelease.versionis a plainCharFieldwith no format validator, so nothing at the model/admin layer restricts its contents.It isn't exploitable in practice: only trusted release-manager staff can set Release.version, and that same group already has direct server/deploy access to the docs-build host, so there's no privilege boundary being crossed. Not treated as a security issue, but worth fixing as routine hardening,
shell=Truewith string-formatted input is bad practice regardless of who can reach it.Fix should be along the lines of:
subprocess.check_call(["make", "translations"], cwd=trans_dir, **extra_kwargs)