{"id":"CVE-2025-55214","aliases":["EUVD-2025-25131","GHSA-p7q8-grrj-3m8w","PYSEC-2026-1273"],"status":"published","title":"Copier safe template has filesystem write access outside destination path","description":"Copier library and CLI app for rendering project templates. From 7.1.0 to before 9.9.1, Copier suggests that it's safe to generate a project from a safe template, i.e. one that doesn't use unsafe features like custom Jinja extensions which would require passing the --UNSAFE,--trust flag. As it turns out, a safe template can currently write files outside the destination path where a project shall be generated or updated. This is possible when rendering a generated directory structure whose rendered path is either a relative parent path or an absolute path. Constructing such paths is possible using Copier's builtin pathjoin Jinja filter and its builtin _copier_conf.sep variable, which is the platform-native path separator. This way, a malicious template author can create a template that overwrites arbitrary files (according to the user's write permissions), e.g., to cause havoc. This vulnerability is fixed in 9.9.1.","severity":{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.0028,"percentile":0.20773,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-22"],"published":"2025-08-18T16:36:46Z","modified":"2026-10-28T02:30:54Z","fixes":[{"ecosystem":"PyPI","package":"copier","fixed_in":["9.9.1"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"copier","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"7.1.0"},{"fixed":"9.9.1"}]}]},{"source":"osv","ecosystem":"PyPI","package":"copier","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"7.1.0"},{"fixed":"9.9.1"}]}],"versions":["7.1.0","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.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"]},{"source":"osv","ecosystem":"PyPI","package":"copier","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"7.1.0"},{"fixed":"9.9.1"}]}],"versions":["7.1.0","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.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"]}],"products":[{"vendor":"copier-org","product":"copier"}],"references":[{"url":"https://github.com/copier-org/copier/security/advisories/GHSA-p7q8-grrj-3m8w","tags":["x_refsource_CONFIRM","advisory","web"]},{"url":"https://github.com/copier-org/copier/commit/fdbc0167cc22780b497e4db176feaf6f024757d6","tags":["x_refsource_MISC","fix","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2025-55214","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-p7q8-grrj-3m8w","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2025/55xxx/CVE-2025-55214.json","tags":["advisory"]},{"url":"https://github.com/copier-org/copier","tags":["package"]},{"url":"https://pypi.org/project/copier","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2025-55214","title":"Copier safe template has filesystem write access outside destination path","description":"Copier library and CLI app for rendering project templates. From 7.1.0 to before 9.9.1, Copier suggests that it's safe to generate a project from a safe template, i.e. one that doesn't use unsafe features like custom Jinja extensions which would require passing the --UNSAFE,--trust flag. As it turns out, a safe template can currently write files outside the destination path where a project shall be generated or updated. This is possible when rendering a generated directory structure whose rendered path is either a relative parent path or an absolute path. Constructing such paths is possible using Copier's builtin pathjoin Jinja filter and its builtin _copier_conf.sep variable, which is the platform-native path separator. This way, a malicious template author can create a template that overwrites arbitrary files (according to the user's write permissions), e.g., to cause havoc. This vulnerability is fixed in 9.9.1.","status":"published","published":"2025-08-18T16:36:46.621Z","modified":"2025-08-18T19:47:31.803Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N","level":"medium","assessor":"cna"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T14:32:52.839698Z"}],"euvd":[{"id":"EUVD-2025-25131","description":"Copier library and CLI app for rendering project templates. From 7.1.0 to before 9.9.1, Copier suggests that it's safe to generate a project from a safe template, i.e. one that doesn't use unsafe features like custom Jinja extensions which would require passing the --UNSAFE,--trust flag. As it turns out, a safe template can currently write files outside the destination path where a project shall be generated or updated. This is possible when rendering a generated directory structure whose rendered path is either a relative parent path or an absolute path. Constructing such paths is possible using Copier's builtin pathjoin Jinja filter and its builtin _copier_conf.sep variable, which is the platform-native path separator. This way, a malicious template author can create a template that overwrites arbitrary files (according to the user's write permissions), e.g., to cause havoc. This vulnerability is fixed in 9.9.1.","status":"published","published":"2025-08-18T16:36:46Z","modified":"2025-08-18T19:47:31Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"updated_at":"2026-11-02T20:31:56.298799Z"}],"ghsa":[{"id":"GHSA-p7q8-grrj-3m8w","title":"Copier's safe template has filesystem write access outside destination path","description":"### Impact\n\nCopier suggests that it's safe to generate a project from a safe template, i.e. one that doesn't use [unsafe](https://copier.readthedocs.io/en/stable/configuring/#unsafe) features like custom Jinja extensions which would require passing the `--UNSAFE,--trust` flag. As it turns out, a safe template can currently write files outside the destination path where a project shall be generated or updated. This is possible when rendering a [generated directory structure](https://copier.readthedocs.io/en/stable/configuring/#generating-a-directory-structure) whose rendered path is either a relative parent path or an absolute path. Constructing such paths is possible using Copier's builtin `pathjoin` Jinja filter and its builtin `_copier_conf.sep` variable, which is the platform-native path separator. This way, a malicious template author can create a template that overwrites arbitrary files (according to the user's write permissions), e.g., to cause havoc.\n\n#### Write access via generated relative path\n\nReproducible example:\n\n```shell\necho \"foo\" \u003e forbidden.txt\nmkdir src/\necho \"bar\" \u003e \"src/{{ pathjoin('..', 'forbidden.txt') }}\"\nuvx copier copy src/ dst/\ncat forbidden.txt\n```\n\n#### Write access via generated absolute path\n\nReproducible example:\n\n- POSIX:\n\n    ```shell\n    # Assumption: The current working directory is `/tmp/test-copier-vulnerability/`\n    echo \"foo\" \u003e forbidden.txt\n    mkdir src/\n    echo \"bar\" \u003e \"src/{{ pathjoin(_copier_conf.sep, 'tmp', 'test-copier-vulnerability', 'forbidden.txt') }}\"\n    uvx --from copier python -O -m copier copy --overwrite src/ dst/\n    cat forbidden.txt\n    ```\n\n- Windows (PowerShell):\n\n    ```powershell\n    # Assumption: The current working directory is `C:\\Users\\\u003cuser\u003e\\Temp\\test-copier-vulnerability`\n    echo \"foo\" \u003e forbidden.txt\n    mkdir src\n    Set-Content -Path src\\copier.yml @'\n    drive:\n      type: str\n      default: \"C:\"\n      when: false\n    '@\n    echo \"bar\" \u003e \"src\\{{ pathjoin(drive, 'Users', '\u003cuser\u003e', 'Temp', 'test-copier-vulnerability', 'forbidden.txt') }}\"\n    uvx --from copier python -O -m copier copy --overwrite src dst\n    cat forbidden.txt\n    ```\n\nThis scenario is slightly less severe, as Copier has a few [assertions of the destination path being relative](https://github.com/copier-org/copier/blob/d106ea543fd26e1ac1b9a3dcef3e99cc70fdf57c/copier/_main.py#L747) which would typically be raised. But `python -O` (or `PYTHONOPTIMIZE=x`) removes asserts, so these guards may be ineffective. In addition, this scenario will prompt for overwrite confirmation or require the `--overwrite` flag for non-interactive mode; yet malicious file writes might go unnoticed.","status":"published","published":"2025-08-18T21:01:07Z","modified":"2025-08-19T09:28:54Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T14:38:53.767052Z"}],"nvd":[{"id":"CVE-2025-55214","description":"Copier library and CLI app for rendering project templates. From 7.1.0 to before 9.9.1, Copier suggests that it's safe to generate a project from a safe template, i.e. one that doesn't use unsafe features like custom Jinja extensions which would require passing the --UNSAFE,--trust flag. As it turns out, a safe template can currently write files outside the destination path where a project shall be generated or updated. This is possible when rendering a generated directory structure whose rendered path is either a relative parent path or an absolute path. Constructing such paths is possible using Copier's builtin pathjoin Jinja filter and its builtin _copier_conf.sep variable, which is the platform-native path separator. This way, a malicious template author can create a template that overwrites arbitrary files (according to the user's write permissions), e.g., to cause havoc. This vulnerability is fixed in 9.9.1.","status":"published","published":"2025-08-18T17:15:30.31Z","modified":"2026-06-17T09:41:28.297Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"medium","assessor":"secondary"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T14:11:24.730342Z"}],"osv":[{"id":"CVE-2025-55214","title":"Copier safe template has filesystem write access outside destination path","description":"Copier library and CLI app for rendering project templates. From 7.1.0 to before 9.9.1, Copier suggests that it's safe to generate a project from a safe template, i.e. one that doesn't use unsafe features like custom Jinja extensions which would require passing the --UNSAFE,--trust flag. As it turns out, a safe template can currently write files outside the destination path where a project shall be generated or updated. This is possible when rendering a generated directory structure whose rendered path is either a relative parent path or an absolute path. Constructing such paths is possible using Copier's builtin pathjoin Jinja filter and its builtin _copier_conf.sep variable, which is the platform-native path separator. This way, a malicious template author can create a template that overwrites arbitrary files (according to the user's write permissions), e.g., to cause havoc. This vulnerability is fixed in 9.9.1.","status":"published","published":"2025-08-18T16:36:46.621Z","modified":"2026-10-28T02:30:54.461788969Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T15:44:50.863921Z"},{"id":"GHSA-p7q8-grrj-3m8w","title":"Copier's safe template has filesystem write access outside destination path","description":"### Impact\n\nCopier suggests that it's safe to generate a project from a safe template, i.e. one that doesn't use [unsafe](https://copier.readthedocs.io/en/stable/configuring/#unsafe) features like custom Jinja extensions which would require passing the `--UNSAFE,--trust` flag. As it turns out, a safe template can currently write files outside the destination path where a project shall be generated or updated. This is possible when rendering a [generated directory structure](https://copier.readthedocs.io/en/stable/configuring/#generating-a-directory-structure) whose rendered path is either a relative parent path or an absolute path. Constructing such paths is possible using Copier's builtin `pathjoin` Jinja filter and its builtin `_copier_conf.sep` variable, which is the platform-native path separator. This way, a malicious template author can create a template that overwrites arbitrary files (according to the user's write permissions), e.g., to cause havoc.\n\n#### Write access via generated relative path\n\nReproducible example:\n\n```shell\necho \"foo\" \u003e forbidden.txt\nmkdir src/\necho \"bar\" \u003e \"src/{{ pathjoin('..', 'forbidden.txt') }}\"\nuvx copier copy src/ dst/\ncat forbidden.txt\n```\n\n#### Write access via generated absolute path\n\nReproducible example:\n\n- POSIX:\n\n    ```shell\n    # Assumption: The current working directory is `/tmp/test-copier-vulnerability/`\n    echo \"foo\" \u003e forbidden.txt\n    mkdir src/\n    echo \"bar\" \u003e \"src/{{ pathjoin(_copier_conf.sep, 'tmp', 'test-copier-vulnerability', 'forbidden.txt') }}\"\n    uvx --from copier python -O -m copier copy --overwrite src/ dst/\n    cat forbidden.txt\n    ```\n\n- Windows (PowerShell):\n\n    ```powershell\n    # Assumption: The current working directory is `C:\\Users\\\u003cuser\u003e\\Temp\\test-copier-vulnerability`\n    echo \"foo\" \u003e forbidden.txt\n    mkdir src\n    Set-Content -Path src\\copier.yml @'\n    drive:\n      type: str\n      default: \"C:\"\n      when: false\n    '@\n    echo \"bar\" \u003e \"src\\{{ pathjoin(drive, 'Users', '\u003cuser\u003e', 'Temp', 'test-copier-vulnerability', 'forbidden.txt') }}\"\n    uvx --from copier python -O -m copier copy --overwrite src dst\n    cat forbidden.txt\n    ```\n\nThis scenario is slightly less severe, as Copier has a few [assertions of the destination path being relative](https://github.com/copier-org/copier/blob/d106ea543fd26e1ac1b9a3dcef3e99cc70fdf57c/copier/_main.py#L747) which would typically be raised. But `python -O` (or `PYTHONOPTIMIZE=x`) removes asserts, so these guards may be ineffective. In addition, this scenario will prompt for overwrite confirmation or require the `--overwrite` flag for non-interactive mode; yet malicious file writes might go unnoticed.","status":"published","published":"2025-08-18T21:01:07Z","modified":"2026-07-07T17:57:04.383208337Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T15:46:52.891208Z"},{"id":"PYSEC-2026-1273","title":"Copier's safe template has filesystem write access outside destination path","description":"### Impact\n\nCopier suggests that it's safe to generate a project from a safe template, i.e. one that doesn't use [unsafe](https://copier.readthedocs.io/en/stable/configuring/#unsafe) features like custom Jinja extensions which would require passing the `--UNSAFE,--trust` flag. As it turns out, a safe template can currently write files outside the destination path where a project shall be generated or updated. This is possible when rendering a [generated directory structure](https://copier.readthedocs.io/en/stable/configuring/#generating-a-directory-structure) whose rendered path is either a relative parent path or an absolute path. Constructing such paths is possible using Copier's builtin `pathjoin` Jinja filter and its builtin `_copier_conf.sep` variable, which is the platform-native path separator. This way, a malicious template author can create a template that overwrites arbitrary files (according to the user's write permissions), e.g., to cause havoc.\n\n#### Write access via generated relative path\n\nReproducible example:\n\n```shell\necho \"foo\" \u003e forbidden.txt\nmkdir src/\necho \"bar\" \u003e \"src/{{ pathjoin('..', 'forbidden.txt') }}\"\nuvx copier copy src/ dst/\ncat forbidden.txt\n```\n\n#### Write access via generated absolute path\n\nReproducible example:\n\n- POSIX:\n\n    ```shell\n    # Assumption: The current working directory is `/tmp/test-copier-vulnerability/`\n    echo \"foo\" \u003e forbidden.txt\n    mkdir src/\n    echo \"bar\" \u003e \"src/{{ pathjoin(_copier_conf.sep, 'tmp', 'test-copier-vulnerability', 'forbidden.txt') }}\"\n    uvx --from copier python -O -m copier copy --overwrite src/ dst/\n    cat forbidden.txt\n    ```\n\n- Windows (PowerShell):\n\n    ```powershell\n    # Assumption: The current working directory is `C:\\Users\\\u003cuser\u003e\\Temp\\test-copier-vulnerability`\n    echo \"foo\" \u003e forbidden.txt\n    mkdir src\n    Set-Content -Path src\\copier.yml @'\n    drive:\n      type: str\n      default: \"C:\"\n      when: false\n    '@\n    echo \"bar\" \u003e \"src\\{{ pathjoin(drive, 'Users', '\u003cuser\u003e', 'Temp', 'test-copier-vulnerability', 'forbidden.txt') }}\"\n    uvx --from copier python -O -m copier copy --overwrite src dst\n    cat forbidden.txt\n    ```\n\nThis scenario is slightly less severe, as Copier has a few [assertions of the destination path being relative](https://github.com/copier-org/copier/blob/d106ea543fd26e1ac1b9a3dcef3e99cc70fdf57c/copier/_main.py#L747) which would typically be raised. But `python -O` (or `PYTHONOPTIMIZE=x`) removes asserts, so these guards may be ineffective. In addition, this scenario will prompt for overwrite confirmation or require the `--overwrite` flag for non-interactive mode; yet malicious file writes might go unnoticed.","status":"published","published":"2026-07-07T16:03:01.48915Z","modified":"2026-07-07T17:47:20.657869518Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"updated_at":"2026-11-02T15:52:54.622769Z"}]}}
