Skip to content

Fix/tool result store read boundary#12059

Merged
anakin87 merged 6 commits into
deepset-ai:mainfrom
Aarkin7:fix/tool-result-store-read-boundary
Jul 21, 2026
Merged

Fix/tool result store read boundary#12059
anakin87 merged 6 commits into
deepset-ai:mainfrom
Aarkin7:fix/tool-result-store-read-boundary

Conversation

@Aarkin7

@Aarkin7 Aarkin7 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Related Issues

Proposed Changes:

FileSystemToolResultStore.write() already restricted writes to the configured root directory, but read() would accept any filesystem path and read it if it was accessible. This made the read path inconsistent with the write path and broke the expected store boundary.

This PR fixes that by:

  • adding a shared path-resolution helper in haystack/hooks/tool_result_offloading/stores.py
  • enforcing the same root-boundary check for both write() and read()
  • rejecting ../ traversal, absolute out-of-root paths, and symlink references that escape the store root
  • updating the tool-result offloading docs to describe references as store-scoped values rather than arbitrary filesystem paths
  • adding a release note for the security hardening

How did you test it?

  • Added regression tests in test/hooks/tool_result_offloading/test_stores.py for:
    • normal round-trip reads
    • parent traversal references
    • absolute references outside the root
    • symlink references inside the root that resolve outside it
  • Ran targeted unit tests:
    • hatch run test:unit -- test/hooks/tool_result_offloading/test_stores.py test/hooks/tool_result_offloading/test_hooks.py
    • hatch run test:unit -- test/hooks test/components/agents/test_agent_hooks.py
  • Ran type checks:
    • hatch run test:types -- haystack/hooks/tool_result_offloading/stores.py test/hooks/tool_result_offloading/test_stores.py
  • Ran format/lint checks:
    • hatch run fmt-check haystack/hooks/tool_result_offloading/stores.py test/hooks/tool_result_offloading/test_stores.py

Notes for the reviewer

  • write() still returns the same kind of reference; read() now enforces that the reference resolves within the configured store root.
  • I also updated the docs example so the read-back tool is bound to the same store scope instead of implying that the returned reference can be treated like a general file path.

Checklist

  • I have read the contributors guidelines and the code of conduct.
  • I have updated the related issue with new insights and changes.
  • I have added unit tests and updated the docstrings.
  • I've used one of the conventional commit types for my PR title: fix:, feat:, build:, chore:, ci:, docs:, style:, refactor:, perf:, test: and added ! in case the PR includes breaking changes.
  • I have documented my code.
  • I have added a release note file, following the contributors guidelines.
  • I have run pre-commit hooks and fixed any issue.

@Aarkin7
Aarkin7 requested a review from a team as a code owner July 17, 2026 16:46
@Aarkin7
Aarkin7 requested review from anakin87 and removed request for a team July 17, 2026 16:46
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

@Aarkin7 is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added topic:tests type:documentation Improvements on the docs labels Jul 17, 2026
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  haystack/hooks/tool_result_offloading
  stores.py
Project Total  

This report was generated by python-coverage-comment-action

@anakin87 anakin87 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR is good.
I left some minor comments.


## Stores

### `FileSystemToolResultStore`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid changing this documentation page. It is still valid.

read(reference: str) -> str
```

Read back the content previously written to `reference`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API reference here is automatically generated and updated, so let's remove this change.

Comment on lines +4 to +7
Harden FileSystemToolResultStore.read() so it only reads references that
resolve within the configured store root. This closes a boundary gap where
callers could previously pass an arbitrary filesystem path to read()
instead of a store-scoped reference returned by write().

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Harden FileSystemToolResultStore.read() so it only reads references that
resolve within the configured store root. This closes a boundary gap where
callers could previously pass an arbitrary filesystem path to read()
instead of a store-scoped reference returned by write().
Harden ``FileSystemToolResultStore.read()`` so it only reads references that
resolve within the configured store root. This closes a boundary gap where
callers could previously pass an arbitrary filesystem path to ``read()``
instead of a store-scoped reference returned by ``write()``.

nitpick

@anakin87 anakin87 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@anakin87
anakin87 enabled auto-merge (squash) July 21, 2026 10:40
@anakin87
anakin87 merged commit 139af73 into deepset-ai:main Jul 21, 2026
22 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic:tests type:documentation Improvements on the docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FileSystemToolResultStore.read() allows reading files outside the configured store root

2 participants