T09 · Insecure Skill Coding Practices
- Location
scripts/audit_memory.py:105- Finding
Explicit paths can rewrite unrelated files without enforceable scope or approval validation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/audit_memory.py:105-109,scripts/audit_memory.py:508-522,scripts/audit_memory.py:624-648
Vulnerability Type: Insufficient target validation and authorization enforcement
Risk Level: MediumVulnerable Code
python def is_allowed_memory_path(self, path: Path) -> bool: suffix = path.suffix.lower() if suffix in self.rules.blocked_memory_extensions: return False return suffix in self.rules.allowed_memory_extensionspython def parse_args(argv: list[str]) -> argparse.Namespace: parser = argparse.ArgumentParser(description="Audit agent memory markdown files.") parser.add_argument("paths", nargs="*", help="Memory files to audit. If omitted, scan likely files in the current workspace.") parser.add_argument( "--mode", choices=["audit-only", "propose-patch", "apply-approved"], default="audit-only", help="Execution mode. Only apply-approved writes files.", ) parser.add_argument("--rules", help="Optional path to a JSON rules file.") parser.add_argument("--json", action="store_true", help="Emit JSON instead of markdown.") parser.add_argument("--summary-json", action="store_true", help="Emit compact machine-readable summary JSON.") parser.add_argument("--candidate", help="Lint a proposed memory entry before writing it to global memory.") parser.add_argument("--include-diff", action="store_true", help="Include unified diffs in markdown output.") parser.add_argument("--output", help="Write report to this path instead of stdout.") parser.add_argument("--write-proposed", help="Write the first proposed cleaned memory to this path.") return parser.parse_args(argv)python def main(argv: list[str] | None = None) -> int: args = parse_args(argv or sys.argv[1:]) rules = RuleConfig.load(Path(args.rules) if args.rules else None) ...[truncated 2960 chars]- Remediation
View remediation
Remediation Suggestions
- Apply the configured likely-memory filename allowlist to explicit paths as well as automatically discovered paths.
- Require targets to reside under user-provided or explicitly configured memory roots.
- Reject known project policies, Skill manifests, prompt templates, source files, and configuration files by default.
- Require an explicit override for unusual filenames, accompanied by a clear warning that the target is outside normal memory scope.
- Separate proposal and application into cryptographically or structurally bound stages. Record the canonical target path, source SHA-256 hash, proposal hash, and approval decision.
- Before writing, verify that the source hash still matches the reviewed version and reject stale approvals.
- Use a distinct approval argument or approval manifest rather than treating the
apply-approvedmode name as proof of consent. - For
--outputand--write-proposed, reject existing destinations by default or require an explicit overwrite option. - Add regression tests demonstrating that unrelated
.md,.txt, and.jsonfiles cannot be applied as memory without an explicit scoped override.
