T09 · Insecure Skill Coding Practices
Error
- Location
- deep_recall.py:410
- Finding
- Requested recall scope is not enforced when selecting and reading files## Vulnerability Details **File Location**: `deep_recall.py:410-447`; related index construction in `memory_indexer.py:100-143` **Vulnerability Type**: Scope authorization bypass and excessive disclosure of workspace memory **Risk Level**: High ### Vulnerable Code ```python # 2. Scan memory files ws = Path(workspace) if workspace else _find_workspace() scanner = MemoryScanner(workspace=ws) scanner.scan(scope=scope) if not scanner.files: return "[DeepRecall] No memory files found in workspace." # 3. Build memory index memory_index = build_memory_index(workspace=ws) # 4. Manager: pick the relevant files try: selected_files = _manager_call(query, memory_index, max_files, provider) except Exception as exc: return f"[DeepRecall] Manager call failed: {exc}" if not selected_files: return "[DeepRecall] No relevant memory files identified for this query." # 5. Workers: extract quotes in parallel worker_results: list[dict] = [] with ThreadPoolExecutor(max_workers=min(len(selected_files), 4)) as pool: futures = {} for fpath in selected_files: content = _read_file(fpath, ws) if content is None: continue fut = pool.submit(_worker_call, query, fpath, content, provider) futures[fut] = fpath ``` The independently constructed index includes all Markdown memory files: ```python memory_dir = workspace / "memory" memory_md = workspace / "MEMORY.md" # Collect all daily logs daily_logs = {} if memory_dir.exists(): for f in sorted(memory_dir.glob("*.md")): # Extract date from filename date_match = re.match(r"(\d{4}-\d{2}-\d{2})", f.name) if date_match: date_str = date_match.group(1) content = f.read_text(errors="replace") topics = extract_topics(content, f.name) daily_logs[date_str] = { "path": f"memory/{f.name}", ...[truncated 3065 chars]
- Remediation
- ## Remediation Suggestions 1. Treat the canonical paths in `scanner.files` as an authorization allowlist: ```python allowed_paths = { item.path.resolve() for item in scanner.files } for fpath in selected_files: resolved = _safe_path(fpath, ws) if resolved is None or resolved not in allowed_paths: logger.warning("Rejected out-of-scope manager selection: %r", fpath) continue ``` 2. Build the manager index directly from the already-scoped scanner result rather than rescanning the workspace. 3. Change `build_memory_index()` to accept an explicit collection of authorized files or a validated scope. 4. Apply scope validation after manager output because model responses are untrusted, even if the prompt instructs the model to honor a scope. 5. Add regression tests proving that `identity` cannot index or read files under `memory/`, and that `memory` cannot select arbitrary project files. 6. Ensure documentation accurately describes both metadata and full-content boundaries for every scope.
