Copier `_subdirectory` allows template root escape via parent-directory traversal
Summary
Copier's _subdirectory setting is documented as the subdirectory to use as the template root. However, the current implementation accepts parent-directory traversal such as .. and uses it directly when selecting the template root.
As a result, a template can escape its own directory and make Copier render files from the parent directory without --UNSAFE.
Details
The relevant code path is:
- the template defines
_subdirectory - Copier renders that string
template_copy_rootreturnsself.template.local_abspath / subdir- Copier walks that directory as the template root
Relevant code:
- https://github.com/copier-org/copier/blob/7aa7021bd73797c982492bac3535515d4484fdb7/copier/_main.py#L1056-L1062
- https://github.com/copier-org/copier/blob/7aa7021bd73797c982492bac3535515d4484fdb7/copier/_template.py#L504-L513
The effective sink is:
subdir = self._render_string(self.template.subdirectory) or ""
return self.template.local_abspath / subdir
There is no check that the resulting path stays inside the template directory.
The documentation for _subdirectory describes it as:
Subdirectory to use as the template root when generating a project.
and explains it as a way to separate template metadata from template source code:
That description fits values like template or poetry, but not ...
PoC
PoC 1: _subdirectory: .. escapes to the parent directory
mkdir -p root/template dst
echo 'loot' > root/loot.txt
printf '%s\n' '_subdirectory: ..' > root/template/copier.yml
copier copy --overwrite root/template dst
find dst -maxdepth 3 -type f | sort
cat dst/loot.txt
Expected output includes:
dst/loot.txt
dst/template/copier.yml
loot
This shows Copier is rendering from root/ rather than from root/template/.
Impact
If a user runs Copier on an untrusted template, that template can change the effective template root and make Copier render files from outside the intended template directory.
Practical impact:
- template-root escape via
.. - rendering of parent-directory files that were not meant to be part of the template
- possible without
--UNSAFE
Affected software
Click a technology to see all vulnerabilities affecting it.
| Platform | Package | Vulnerable versions | Fixed in |
|---|---|---|---|
| Python (PyPI) | copier | < 9.14.1 | 9.14.1 |
References
- https://github.com/copier-org/copier/releases/tag/v9.14.1
- https://github.com/copier-org/copier/commit/cb80a3ffc9c3787de3ed837e04ca29a0ff8ca3df
- https://github.com/copier-org/copier/security/advisories/GHSA-85v3-4m8g-hrh6
- https://nvd.nist.gov/vuln/detail/CVE-2026-34726
- https://github.com/copier-org/copier
- CVSS vector
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N- Weakness (CWE)
CWE-22- Platform
- Python (PyPI)
- Package
copier- Disclosed
- 01.04.2026
- Updated
- 11.10.2026 14:17
Sources and licenses
OSV / GitHub Advisory Database - PYSEC-2026-2134 - PyPA Advisory Database; CC BY 4.0
OSV / GitHub Advisory Database - GHSA-85v3-4m8g-hrh6 - CC BY 4.0
Vulnerability history: copier
All published vulnerabilities of this package (Python (PyPI)), newest first. Shows whether this is a one-off slip or a package that needs watching.
- Total entries
- 7
- First → latest
- 08.2025 08.2026
- Without a fix
- 0
- Exploited in attacks
- 0
Severity breakdown
- High 2
- Medium 5
Disclosures per year
- 2025: 2
- 2026: 5
-
Copier `_subdirectory` allows template root escape via parent-directory traversal this entry
Know which vulnerabilities affect your application
With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.