Skip to content

import_into writes to attacker-controlled paths outside the store root #18

Description

@laurail

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.

Activity

  1. PatrickSun93 commented on Oct 1, 2026

    @PatrickSun93

    I think this one can be closed: it was fixed by #15 ("refuse path traversal in import_into", merged 2026-09-23). That PR didn't reference this issue, so it stayed open.

    I checked on current main (243868db). import_into now resolves the target and refuses anything outside store.root. The payload from this report ("path": "../../escape.txt") raises ValueError: path traversal refused: ../../escape.txt, and no file is written outside the store.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions