T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/yotta_verify.py:493
- Finding
- Tarball extraction can escape the temporary scan directory through link entries<![CDATA[ ## Vulnerability Details **File Location**: `scripts/yotta_verify.py:493-500` **Vulnerability Type**: Unsafe archive extraction **Risk Level**: High ### Vulnerable Code ```python def _safe_extract(tf, dest): """Extract a tarball with manual path-traversal protection.""" for member in tf.getmembers(): name = member.name if name.startswith(("/", "\\")) or ".." in Path(name).parts: raise ValueError("tarball contains dangerous path: %s" % name) tf.extractall(dest) ``` ### Technical Analysis The validation only inspects the textual name of each archive member. It does not reject symbolic links, hard links, device entries, or other special members, and it does not verify where a link target resolves. A malicious archive can therefore contain a link whose member name appears safe but whose target points outside the temporary extraction directory. A later archive member can then write through that link. This defeats the intended parent-directory and absolute-path checks. The implementation supports Python 3.8+, where safe extraction filters are not consistently available by default, making explicit validation necessary. ### Attack Path 1. An attacker creates a `.tgz` or `.tar.gz` package containing a symbolic-link or hard-link entry. 2. The link member has a benign relative name and therefore passes the `name.startswith()` and `Path(name).parts` checks. 3. The link target resolves outside the temporary extraction root. 4. A subsequent archive member is extracted through the link. 5. `tarfile.extractall()` writes the member outside the intended temporary directory. 6. The overwrite occurs when a user merely asks the tool to scan the attacker-controlled archive. ### Impact Assessment The attacker may create or overwrite files accessible to the account running the scanner. The exact impact depends on filesystem permissions and the chosen target, but can include modification of user configuration, Agent skill fil ...[truncated 188 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not call unrestricted `extractall()` on untrusted archives. - Reject symbolic links, hard links, device nodes, FIFOs, and other non-regular entries unless they are explicitly required. - Resolve the destination of every member and require it to remain beneath `Path(dest).resolve()`. - Validate both member paths and link targets. - Extract regular files individually after validation. - Add regression tests for: - Absolute member paths - Parent-directory traversal - Symbolic-link traversal - Hard-link traversal - Link chains - Special filesystem entries - Consider scanning tar members directly without extracting them to disk. ]]>
