High

ObsidianReader Symlink Traversal Arbitrary File Read

Some tools that ingest Obsidian-style markdown vaults (such as llama_index's ObsidianReader) follow symbolic links without checking whether the linked file actually lives inside the vault folder. An attacker who can plant a symlink in the vault can make the ingestion process read credentials or secrets stored elsewhere on disk, and those contents get pulled into whatever the reader does next (indexing, embedding, summarizing, etc.).

How the attack works

An attacker places a symbolic link inside a markdown vault that points to a file outside the vault root, such as a credentials or environment file. When the vault-ingestion process runs, it reads vault content — either something under a ".obsidian" marker folder or a batch of ".md" files under one parent directory — and later, in that same run, follows the symlink and reads the out-of-vault secret file. Because the reader never resolves symlinks to their real path or confirms the target stays inside the vault, the read succeeds silently and the secret's contents flow into the ingestion pipeline. The detection ties both reads to the exact same process instance to confirm they happened in one ingestion run, and requires the vault read to come first, which distinguishes this from normal startup config loading.

Netzilo detection

Netzilo reports this behaviour when it is observed.

Signature ID
6f3b1c92-8a4d-4f57-9b21-7d0c5e4a18ab
Severity
High

Why it matters

An attacker who can drop a file into a vault that gets indexed can exfiltrate credentials, API keys, or other sensitive files the ingestion process has permission to read, without needing separate access to the ingestion host.

What you can do

  • Configure markdown/vault ingestion tools to resolve symlinks to their real path and reject any target outside the vault root before reading.
  • Restrict who can write files into vaults that are auto-ingested, especially shared or synced vaults.
  • Run ingestion processes with the minimum file permissions needed — do not let them read credential files, .env, or config files outside the vault.
  • Review flagged reports for the exact out-of-vault path; some legitimate workflows intentionally symlink external notes into a vault, so confirm intent before treating it as an incident.

Known benign look-alikes

  • A knowledge-base indexing job that legitimately ingests an Obsidian vault and, in the same process, loads its own ".env" / ".npmrc" for API keys. Mitigated by requiring the out-of-vault secret read to occur AFTER the first vault file read (dotenv-style config loading happens at start-up, before ingestion) and by reporting rather than blocking.
  • A user who deliberately symlinks notes stored outside the vault into it (a documented Obsidian workflow). This is a genuine true-positive behaviour with a benign intent; the report names the exact out-of-vault path so an analyst can confirm it in seconds.
  • Developer agents that index a vault and separately read "~/.gitconfig" or shell history in the same window. Those paths are secondary evidence only and can never satisfy the required anchor on their own.
  • Backup / sync helpers spawned under the agent process tree that walk both the vault and the home directory. Bounded by the 5-minute window, the ordering requirement and the per-instance scoping, but still possible - hence report.
  • Short lineage (an unmonitored shell above the loader) yields "attribution degraded" in the reason string; the detection is still instance-exact for the reading process itself.

References

Related threats