import_into writes to attacker-controlled paths outside the store root
Severity: Critical
File: packages/core/src/agent_memory/core/portability.py:48
import_into builds the target path as store.root / str(entry[KEY_PATH]) and writes
to it without validating that the result stays within the store root. A crafted export
file with "path": "../../etc/cron.d/malicious" escapes the store directory via
pathlib.Path's .. traversal. pathlib.Path("store") / "../../etc/x" resolves to
/etc/x on the filesystem.
def import_into(store: Store, payload: dict[str, object]) -> int:
...
for entry in files if isinstance(files, list) else []:
target = store.root / str(entry[KEY_PATH]) # no traversal check
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(str(entry[KEY_TEXT]), encoding="utf-8")
Why it matters
mem import is the documented migration path between stores. An operator who imports
an untrusted export file can have arbitrary files written anywhere the process has
write permission. The fix is to resolve the target and verify target.resolve().is_relative_to(store.root.resolve())
before writing.
import_into writes to attacker-controlled paths outside the store root
Severity: Critical
File:
packages/core/src/agent_memory/core/portability.py:48import_intobuilds the target path asstore.root / str(entry[KEY_PATH])and writesto it without validating that the result stays within the store root. A crafted export
file with
"path": "../../etc/cron.d/malicious"escapes the store directory viapathlib.Path's..traversal.pathlib.Path("store") / "../../etc/x"resolves to/etc/xon the filesystem.Why it matters
mem importis the documented migration path between stores. An operator who importsan untrusted export file can have arbitrary files written anywhere the process has
write permission. The fix is to resolve the target and verify
target.resolve().is_relative_to(store.root.resolve())before writing.