T09 · Insecure Skill Coding Practices
- Location
scripts/append_to_context.py:123- Finding
Unrestricted Context Path Allows Arbitrary File Modification
- Content
View full analysis
Vulnerability Details
File Location:
scripts/append_to_context.py, lines 123–127 and 174–175
Vulnerability Type: Arbitrary file append through insufficient path validation
Risk Level: HighVulnerable Code:
python context_path = Path(args.context_file).expanduser().resolve() if not context_path.is_file(): print(f"Error: context file not found: {context_path}", file=sys.stderr) sys.exit(1)python with open(context_path, "a", encoding="utf-8") as f: f.write(entry)Technical Analysis
The
--context-fileargument is entirely caller-controlled. Although the path is normalized withresolve()and checked withis_file(), the implementation does not verify that it is located inside the intendedsub-agentscontext directory. It also does not validate that the target has the expected context-file format.Consequently, any existing file writable by the current process can be selected as the append target. Resolving the path does not provide authorization; it only creates an absolute canonical path. Symlinks are also followed during resolution without an explicit policy rejecting them.
The appended body can come from
--content,--content-file, or standard input. Although the helper surrounds most content with Markdown-style headers, the operation can still corrupt arbitrary files or inject data into formats where appended content has semantic meaning.Attack Path
- An attacker directly invokes the helper or influences an Agent-generated invocation.
- The attacker supplies an existing writable file outside the context directory through
--context-file. - The attacker supplies controlled data through
--content,--content-file, or standard input. - The script resolves the path but performs no containment or context-format validation.
- The generated entry is appended to the selected file.
- The target is corrupted or, where the target format pro ...[truncated 1082 chars]
- Remediation
View remediation
Remediation Suggestions
-
Define one authoritative context root and require every target to remain within it after canonicalization:
python context_root = CONTEXT_DIR.resolve() context_path = Path(args.context_file).expanduser().resolve(strict=True) if not context_path.is_relative_to(context_root): print("Error: context file is outside the permitted directory.", file=sys.stderr) sys.exit(1) -
Reject symbolic links explicitly when the security model does not require them. Where supported, use no-follow file-opening semantics to reduce time-of-check/time-of-use and symlink-swap risks.
-
Require the
.mdextension and validate the expected context structure, including the metadata header and context-file declaration, before appending. -
Verify that the metadata path matches the actual canonical path.
-
Open the target using descriptor-based APIs with restrictive flags, then validate and append through the same descriptor to reduce race conditions.
-
Add negative tests covering absolute paths outside the context root,
..traversal, symlinks, malformed context files, and race-condition scenarios.
-
