T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/memory_capture.py:345- Finding
Crafted Backup Archives Can Overwrite Arbitrary Files Within the Target Workspace
- Content
View full analysis
Vulnerability Details
File Location:
scripts/memory_capture.py:345-361andscripts/memory_capture.py:479-483
Vulnerability Type: Insufficient archive-member allowlisting
Risk Level: MediumVulnerable Code
python def safe_members_from_manifest(archive: zipfile.ZipFile) -> list[str]: try: manifest = json.loads(archive.read("manifest.json").decode("utf-8")) except KeyError as error: raise ValueError("Archive is missing manifest.json.") from error included_paths = manifest.get("included_paths") if not isinstance(included_paths, list) or not all(isinstance(item, str) for item in included_paths): raise ValueError("Archive manifest has invalid included_paths.") archive_names = set(archive.namelist()) safe_paths: list[str] = [] for item in included_paths: pure_path = PurePosixPath(item) if pure_path.is_absolute() or ".." in pure_path.parts: raise ValueError(f"Archive contains unsafe path: {item}") if item not in archive_names: raise ValueError(f"Archive is missing expected file: {item}") safe_paths.append(item) return safe_pathspython def restore_archive(archive: zipfile.ZipFile, workspace: Path, members: list[str]) -> None: for member in members: target_path = workspace / PurePosixPath(member) target_path.parent.mkdir(parents=True, exist_ok=True) target_path.write_bytes(archive.read(member))Technical Analysis
The archive validation rejects absolute paths and conventional
..traversal, but it does not enforce the documented import boundary. Imported files are expected to be limited to the supported root files—MEMORY.md,SESSION-STATE.md,working-buffer.md, andmemory-capture.md—or descendants ofmemory/andattachments/.Instead, every relative path listed in attacker-controlled
manifest.jsonis acce ...[truncated 1974 chars]- Remediation
View remediation
Remediation Suggestions
Enforce an explicit allowlist before performing any backup, deletion, or restoration:
- Accept only the exact supported root files:
MEMORY.mdSESSION-STATE.mdworking-buffer.mdmemory-capture.md
- Accept other entries only when their normalized paths are descendants of
memory/orattachments/. - Reject empty names, directory entries, duplicate entries, NUL characters, absolute paths,
..components, and platform-specific path ambiguities. - Validate
archive_versionandarchive_kindbefore restoration. - Verify that every archive member intended for restoration is a regular file.
- Complete validation of the entire archive before creating the pre-import backup or invoking
--clean. - Extract into a temporary staging directory first and commit the validated result only after all reads and writes succeed.
- Add regression tests using manifests that reference
AGENTS.md,.env, nested script paths, duplicate entries, and unsupported archive members.
- Accept only the exact supported root files:
