Executive brief
Copier is a Python tool used for creating and updating projects from templates. An attacker who controls a project's configuration can craft a malicious template URL containing path-traversal sequences (e.g., `..`) that bypasses the trust settings intended to prevent unsafe templates from running. This allows arbitrary commands to execute via template tasks without user confirmation, compromising the integrity and security of projects being created or updated.
Technical details
The vulnerability is a path-traversal authorization bypass in the trust-prefix matching logic (copier/_settings.py:141-146). The code uses raw `str.startswith()` to compare template URLs against trusted prefixes, but the _normalize() function only expands `~` and does not resolve `..` or `.` segments. Meanwhile, when the template is actually fetched, the URL is normalized via `Path.resolve()` (local paths) or libcurl dot-segment removal (HTTPS). An attacker-controlled URL with embedded `..` (e.g., `/trusted_prefix/../attacker/template`) passes the trust check because it textually starts with the trusted prefix, but resolves to a different location. Since the untrusted-template gate in copier/_main.py:293 returns early when trust matches, the malicious template's tasks, migrations, and jinja_extensions execute without prompting. This is most severe on `copier update`, which reads the template URL from the project's `.copier-answers.yml`, meaning an attacker who distributes a project controls the URL. The fix requires normalizing both sides of the comparison before the prefix test, using `Path(t).resolve()` and segment containment checks (already used elsewhere in the codebase).
Affected products
- copier-org copier >=9.5.0, <=9.15.1
Timeline
- 2026-08-19: disclosed
- 2026-06-13: patched: Version 9.15.2 released with fix