T09 · Insecure Skill Coding Practices
- Location
scripts/new_memory_object.py:49- Finding
Path Traversal in Memory Object Creation Permits Writes Outside the Intended Directory
- Content
View full analysis
Vulnerability Details
File Location:
scripts/new_memory_object.py:49-59, 76-79; exposed throughscripts/memory_cli.py:144-147, 181-187
Vulnerability Type: Unrestricted path construction from a user-controlled slug
Risk Level: HighVulnerable Code
python # scripts/new_memory_object.py:49-59 def main(): ap = argparse.ArgumentParser() ap.add_argument('--type', required=True, choices=sorted(TYPE_DIR_MAP.keys())) ap.add_argument('--domain', required=True) ap.add_argument('--slug', required=True) ap.add_argument('--title', required=True) ap.add_argument('--summary', default='TODO: add summary') args = ap.parse_args() target_dir = os.path.join(OBJECTS_DIR, TYPE_DIR_MAP[args.type]) os.makedirs(target_dir, exist_ok=True) path = os.path.join(target_dir, f'{args.slug}.yaml')python # scripts/new_memory_object.py:76-79 with open(path, 'w', encoding='utf-8') as f: f.write(dump_yaml(blob)) print(json.dumps({'ok': True, 'path': path}, ensure_ascii=False, indent=2))python # scripts/memory_cli.py:144-147 def cmd_new_object(args): argv = ['--type', args.type, '--domain', args.domain, '--slug', args.slug, '--title', args.title, '--summary', args.summary] run('new_memory_object.py', args=argv) run('generate_memory_index.py')python # scripts/memory_cli.py:181-187 p_obj = sub.add_parser('new-object') p_obj.add_argument('--type', required=True) p_obj.add_argument('--domain', required=True) p_obj.add_argument('--slug', required=True) p_obj.add_argument('--title', required=True) p_obj.add_argument('--summary', required=True) p_obj.set_defaults(func=cmd_new_object)Technical Analysis
The
--slugargument is incorporated directly into a filesystem path. The implementation does not reject absolute paths, directory separators, or..traversal components, and it does not verify that the resolved destination remains undermemory/objects/<type-directory>.For ex ...[truncated 1964 chars]
- Remediation
View remediation
Remediation Suggestions
- Restrict slugs to a conservative allowlist, for example:
python import re if not re.fullmatch(r'[a-z0-9][a-z0-9_-]{0,63}', args.slug): raise SystemExit('Invalid slug')- Resolve and validate the destination before writing:
python base = Path(target_dir).resolve() destination = (base / f'{args.slug}.yaml').resolve() if not destination.is_relative_to(base): raise SystemExit('Destination escapes the object directory')-
Explicitly reject absolute paths,
..,/, backslashes, null characters, and platform-specific path separators. -
Consider symlink attacks. Validate resolved parent directories and ensure writable object directories are not controlled by untrusted users.
-
Use exclusive creation mode to avoid time-of-check/time-of-use races:
python with destination.open('x', encoding='utf-8') as f: f.write(dump_yaml(blob))- Apply the same centralized slug-validation function to every object and topic creation entry point, including direct script invocation and
memory_cli.py.
