deepset-ai / deepset-ai/haystack

FileSystemSkillStore advertises escaping symlinks as readable bundled files

Open
#12,820 0 comments 0 reactions 1 assignee View on GitHub

@sjrl is already working on this.

Since Sep 20, 2026.

Dominant language
Python
Stars
26.6k
Forks
3.2k
Avg merge
1d 3h
Merged PRs (30d)
194

Description

FileSystemSkillStore._list_skill_files() includes symlinks whose resolved targets are outside the skill directory. However, read_skill_file() correctly rejects those same paths as traversal.

As a result, load_skill() gives the model a manifest containing a file it can never read. The model may select that advertised file, waste a tool call, and receive a PermissionError.

Reproduction
from pathlib import Path
from tempfile import TemporaryDirectory
from haystack.skill_stores.file_system.skill_store import FileSystemSkillStore

with TemporaryDirectory() as d:
    root = Path(d)
    skill = root / "demo"
    skill.mkdir()
    (skill / "SKILL.md").write_text(
        "---\ndescription: demo\n---\nbody", encoding="utf-8"
    )
    secret = root / "outside.txt"
    secret.write_text("outside", encoding="utf-8")
    (skill / "outside-link.txt").symlink_to(secret)

    store = FileSystemSkillStore(root)
    print(store.load_skill("demo")[1])
    store.read_skill_file("demo", "outside-link.txt")

Output:

['outside-link.txt']
PermissionError: Cannot read 'outside-link.txt' from skill 'demo': the path resolves outside the skill directory.
Expected

The bundled-file manifest should only contain paths that read_skill_file() can access within the skill root.

Proposed fix

Resolve each discovered path and exclude entries whose targets are outside the resolved skill directory. I have a small patch and regression test ready.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.