T09 · Insecure Skill Coding Practices
- Location
scripts/batch-download.py:10- Finding
Arbitrary File Write Through an Unsanitized Destination Filename
- Content
View full analysis
Vulnerability Details
File Location:
scripts/batch-download.py, lines 10–18 and 37–47
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: HighVulnerable Code
python def download_file(url: str, dest_path: Path, timeout: int = 30) -> bool: """下载单个文件""" try: req = urllib.request.Request(url, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' }) with urllib.request.urlopen(req, timeout=timeout) as response: data = response.read() dest_path.write_bytes(data)python for item in sys.argv[2:]: if '|' in item: url, filename = item.split('|', 1) else: url = item filename = url.split('/')[-1].split('?')[0] if not filename: print(f"[SKIP] 无法从URL提取文件名: {url}") continue dest_path = dest_dir / filename ok = download_file(url.strip(), dest_path)Technical Analysis
The filename following the
URL|filenameargument is controlled by the caller and is joined directly todest_dir. The implementation does not reject absolute paths, parent-directory components, platform-specific path separators, or symbolic-link destinations.For example, a filename such as
../../configuration.jsoncan resolve outside the intended download directory. Withpathlib, an absolute filename may also cause the intended destination directory to be discarded. The resulting path is passed toPath.write_bytes(), which overwrites an existing file without confirmation.No post-resolution containment check is performed to verify that the final destination remains beneath
dest_dir. The code also does not prevent writes through pre-existing symbolic links.Attack Path
- An attacker or untrusted user convinces the Agent to process a crafted material-download request.
- The request supplies an arg ...[truncated 1178 chars]
- Remediation
View remediation
Remediation Suggestions
- Treat supplied filenames strictly as basenames:
- Reject absolute paths.
- Reject
..path components. - Reject directory separators and platform-specific alternate separators.
- Apply a conservative filename-character allowlist.
- Resolve and validate the destination before writing:
- Resolve
dest_dirto a canonical path. - Resolve the candidate destination.
- Verify that the candidate is a child of the canonical destination directory.
- Resolve
- Reject symbolic-link destinations and inspect parent directories for unexpected links where the threat model includes local attackers.
- Avoid silently overwriting files. Use exclusive creation mode or require explicit authorization before replacement.
- Generate server-side filenames where possible and retain the original name only as metadata.
- Log rejected paths without exposing sensitive filesystem details.
A safe design should enforce containment immediately before opening the destination, rather than relying only on string-based filtering.
- Treat supplied filenames strictly as basenames:
