T09 · Insecure Skill Coding Practices
- Location
scripts/apply_config_bundle.py:27- Finding
Archive extraction permits path traversal and unsafe link handling
- Content
View full analysis
None: destination = destination.resolve() for member in archive.getmembers(): member_path = (destination / member.name).resolve() if not str(member_path).startswith(str(destination)): raise ValueError(f"Unsafe tar member path: {member.name}") archive.extractall(path=destination) ``` ### Technical Analysis The extraction guard uses a string-prefix comparison to determine whether a member remains under the extraction directory. String prefixes do not represent filesystem ancestry. For example, if the extraction directory is `/tmp/bundle`, a resolved path such as `/tmp/bundle-evil/file` still begins with the string `/tmp/bundle`. The implementation also does not reject or validate symbolic links and hard links. A crafted archive can contain a link whose target points outside the extraction directory and subsequent members that write through that link. Calling `archive.extractall()` after only validating member names does not reliably contain those link-based writes. The bundle is therefore treated as trusted filesystem input even though it can originate from another machine or an untrusted transfer channel. ### Attack Path 1. An attacker creates a tar archive containing traversal paths or archive links that resolve outside the intended temporary extraction directory. 2. The attacker supplies the archive as a migration bundle. 3. The user runs `apply_config_bundle.py --bundle `. 4. The flawed string-prefix check accepts a path that is not actually a descendant of the extraction directory, or fails to account for a malicious link target. 5. `archive.extractall()` writes an archive member outside the temporary directory. 6. Files accessible t ...[truncated 538 chars]- Remediation
View remediation
