{"id":"GHSA-85v3-4m8g-hrh6","summary":"Copier `_subdirectory` allows template root escape via parent-directory traversal","details":"### Summary\n\nCopier'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.\n\nAs a result, a template can escape its own directory and make Copier render files from the parent directory without `--UNSAFE`.\n\n### Details\n\nThe relevant code path is:\n\n1. the template defines `_subdirectory`\n2. Copier renders that string\n3. `template_copy_root` returns `self.template.local_abspath / subdir`\n4. Copier walks that directory as the template root\n\nRelevant code:\n\n- \u003chttps://github.com/copier-org/copier/blob/7aa7021bd73797c982492bac3535515d4484fdb7/copier/_main.py#L1056-L1062\u003e\n- \u003chttps://github.com/copier-org/copier/blob/7aa7021bd73797c982492bac3535515d4484fdb7/copier/_template.py#L504-L513\u003e\n\nThe effective sink is:\n\n```python\nsubdir = self._render_string(self.template.subdirectory) or \"\"\nreturn self.template.local_abspath / subdir\n```\n\nThere is no check that the resulting path stays inside the template directory.\n\nThe documentation for `_subdirectory` describes it as:\n\n\u003e Subdirectory to use as the template root when generating a project.\n\nand explains it as a way to separate template metadata from template source code:\n\n\u003chttps://github.com/copier-org/copier/blob/7aa7021bd73797c982492bac3535515d4484fdb7/docs/configuring.md#L1582-L1646\u003e\n\nThat description fits values like `template` or `poetry`, but not `..`.\n\n### PoC\n\n#### PoC 1: `_subdirectory: ..` escapes to the parent directory\n\n```sh\nmkdir -p root/template dst\necho 'loot' \u003e root/loot.txt\nprintf '%s\\n' '_subdirectory: ..' \u003e root/template/copier.yml\n\ncopier copy --overwrite root/template dst\nfind dst -maxdepth 3 -type f | sort\ncat dst/loot.txt\n```\n\nExpected output includes:\n\n```text\ndst/loot.txt\ndst/template/copier.yml\nloot\n```\n\nThis shows Copier is rendering from `root/` rather than from `root/template/`.\n\n### Impact\n\nIf 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.\n\nPractical impact:\n\n- template-root escape via `..`\n- rendering of parent-directory files that were not meant to be part of the template\n- possible without `--UNSAFE`","aliases":["CVE-2026-34726","PYSEC-2026-2134"],"modified":"2026-07-13T07:26:50.377650565Z","published":"2026-04-01T22:28:49Z","database_specific":{"github_reviewed_at":"2026-04-01T22:28:49Z","nvd_published_at":"2026-04-02T19:21:32Z","cwe_ids":["CWE-22"],"severity":"MODERATE","github_reviewed":true},"references":[{"type":"WEB","url":"https://github.com/copier-org/copier/security/advisories/GHSA-85v3-4m8g-hrh6"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34726"},{"type":"WEB","url":"https://github.com/copier-org/copier/commit/cb80a3ffc9c3787de3ed837e04ca29a0ff8ca3df"},{"type":"PACKAGE","url":"https://github.com/copier-org/copier"},{"type":"WEB","url":"https://github.com/copier-org/copier/releases/tag/v9.14.1"}],"affected":[{"package":{"name":"copier","ecosystem":"PyPI","purl":"pkg:pypi/copier"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"9.14.1"}]}],"versions":["2.0.0","2.0.1","2.1.0","2.2.1","2.2.2","2.2.3","2.3","2.3.1","2.3.2","2.3.3","2.4.0","2.4.1","2.4.2","2.5.0","2.5.1","3.0.0a3","3.0.0a5","3.0.0a6","3.0.0a7","3.0.0a8","3.0.0b1","3.0.1","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.1.0","3.2.0","4.0.0","4.0.1","4.0.2","4.1.0","5.0.0","5.1.0","6.0.0","6.0.0a0","6.0.0a2","6.0.0a3","6.0.0a4","6.0.0a5","6.0.0a6","6.0.0a7","6.0.0a9","6.0.0b0","6.1.0","6.2.0","7.0.1","7.1.0","7.1.0a0","7.2.0","8.0.0","8.1.0","8.2.0","8.3.0","9.0.1","9.1.0","9.1.1","9.10.0","9.10.1","9.10.2","9.10.3","9.11.0","9.11.1","9.11.2","9.11.3","9.12.0","9.13.0","9.13.1","9.14.0","9.2.0","9.3.0","9.3.1","9.4.0","9.4.1","9.5.0","9.6.0","9.7.0","9.7.1","9.8.0","9.9.0","9.9.1"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-85v3-4m8g-hrh6/GHSA-85v3-4m8g-hrh6.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N"}]}