DEV Community

Cover image for CVE-2026-76832: Agno PythonTools Path Traversal Escapes base_dir
Michael Kantor for HOL (Hashgraph Online)

Posted on Originally published at hol.org

CVE-2026-76832: Agno PythonTools Path Traversal Escapes base_dir

Originally published at HOL

CVE-2026-76832: Agno PythonTools Path Traversal Escapes base_dir

TL;DR: Agno's PythonTools built filesystem paths with self.base_dir.joinpath(file_name) and never checked that the resolved path stayed inside base_dir. read_file, save_to_file_and_run, and run_python_file_return_variable all take file_name. If an attacker can set that argument, through a direct tool call or through prompt injection into agent-processed content, the agent process can read, write, or run Python files outside the intended directory as the process user. The bug is CWE-22. It applies when PythonTools is enabled on an agent. VulnCheck scores it 8.5 High under CVSS 4.0 (AV:A, UI:A) and 8.8 High under CVSS 3.1. Agno patched it in v2.3.24 on 2026-01-08. Current PyPI is 2.9.0. Upgrade and confirm >= 2.3.24. Setting restrict_to_base_dir=False turns the check off and reopens the hole.

What happened

Agno (PyPI package agno) is an agent framework. PythonTools lets an agent save, read, and run Python files under a configured base_dir. If base_dir is omitted, the toolkit uses the process current working directory.

Before the patch, those file tools treated file_name as a relative path and concatenated it with base_dir. pathlib.Path.joinpath does not reject parent-directory segments. The resulting path was passed to read_text, write_text, or runpy.run_path with no resolve() plus containment check. The advertised base directory was a prefix, not a boundary. That is CWE-22.

The reporter, Ali Raza (locus-x64), disclosed it to Agno support on 2026-01-07. Maintainer Yuvaraj Shanmugam acknowledged the report on 2026-01-08, the day the fix shipped. oss-security carried the write-up on 2026-01-27 while a CVE was still pending. VulnCheck assigned CVE-2026-76832 on 2026-08-19. The code fix is seven months old. Installs that never upgraded, and installs that opted out of the new default, remain in scope.

Affected versions

  • Package: PyPI agno (vendor Agno AGI)
  • Affected: versions before 2.3.24. The vulnerable joinpath construction is present in the v2.3.23 tree at libs/agno/agno/tools/python.py. The VulnCheck CNA record versions the product against git commit 710d7e7 rather than a PyPI range. That hash is the fix commit, not a release number.
  • Fixed: 2.3.24, GitHub release and PyPI upload on 2026-01-08. PR 5940, commit 710d7e7f846f93b7a3eadfd3e77075428c39e803.
  • Current PyPI latest: 2.9.0. The restrict_to_base_dir=True default and _check_path call sites are still present on the v2.9.0 tag.
  • CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
  • CVSS: VulnCheck CNA, CVSS 4.0 8.5 High (CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N). CVSS 3.1 8.8 High (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H). NVD status is Received as of 2026-08-19. There is no NVD analysis score yet. Not listed in CISA KEV. No GitHub Security Advisory for CVE-2026-76832. Other Agno GHSAs exist for different bugs, including CVE-2026-35002 (eval injection), which was also fixed in 2.3.24.
  • Preconditions: PythonTools enabled on an agent. The attacker must influence file_name.

How to fix

Upgrade the PyPI package:

pip install --upgrade agno
Enter fullscreen mode Exit fullscreen mode

Confirm the installed version:

pip show agno
Enter fullscreen mode Exit fullscreen mode

The Version field must be 2.3.24 or newer. 2.9.0 is the current PyPI release.

After upgrading, do not set restrict_to_base_dir=False on PythonTools unless you have a documented reason and a separate containment boundary. That flag is the vendor opt-out. It restores unconstrained path joining and reopens this CVE.

Inventory agents that construct Agent(tools=[PythonTools(...)]) or the equivalent. If the agent does not need file save, read, or run, drop PythonTools, or use exclude_tools to remove read_file, save_to_file_and_run, and run_python_file_return_variable.

The path check is not a sandbox. run_python_code, pip_install_package, and uv_pip_install_package still execute or install with the process user's privileges. Agno's docs still say to keep human supervision and to run untrusted execution in a container, VM, or Daytona.

Technical details

Vulnerable construction in v2.3.23 libs/agno/agno/tools/python.py:

file_path = self.base_dir.joinpath(file_name)
Enter fullscreen mode Exit fullscreen mode

That line appeared in save_to_file_and_run, run_python_file_return_variable, and read_file. The CVE text names the tool actions save_to_file and run_python_file. The Python methods are the names above.

Commit 710d7e7 (PR 5940, "feat: add restrict_to_base_dir param to PythonTools and MLXTranscribeTools") does three things:

1. Resolves base_dir at toolkit init. 2. Adds restrict_to_base_dir: bool = True. 3. Routes file operations through Toolkit._check_path, which resolve()s the joined path and calls Path.relative_to(base_dir). A path that is not inside base_dir returns (False, base_dir) and the tool returns an error string instead of touching the file.

If restrict_to_base_dir is False, _check_path returns (True, file_path) with no containment test. That is an intentional opt-out, and it reopens CVE-2026-76832.

The same PR applied the helper to FileTools and MLXTranscribeTools. CVE-2026-76832 is scoped to PythonTools.

The v2.3.24 GitHub notes describe the change as "Forbid tools to operate out of base directory." Agno's product changelog calls it "Safer defaults: tools are restricted to their base directory by default" and flags it as a breaking change for workloads that previously wrote outside base_dir.

No GitHub Security Advisory exists for CVE-2026-76832 as of this writing. HOL Guard's evidence pack still has cvssScore: null because NVD analysis has not landed. The scores above come from the published VulnCheck CNA CVE document.

This article is the operator write-up: what broke, who is affected, and how to fix it. The HOL Guard evidence page is the source record for CVE-2026-76832.

References

Top comments (0)