Skip to content

security: enforce repository boundaries for model-invoked file tools #17

Description

@jadercorrea

Problem

Model-invoked filesystem tools do not enforce the repository boundary.

readFile builds its target with:

fullPath := filepath.Join(workdir, path)
content, err := os.ReadFile(fullPath)

A relative path containing .. can therefore escape workdir. A symlink
inside the repository can also resolve to a file outside it. Because tool
results are returned to the agent, local file contents can be sent to the
configured model provider.

listFiles accepts a caller-controlled path and walks it without the same
boundary validation. Write and patch tools should be audited against the same
invariant.

Safe reproduction

Use two temporary sibling directories:

  1. Put outside.txt in the parent temporary directory.
  2. Use the other directory as workdir.
  3. Call read_file with ../outside.txt.
  4. Assert that the tool rejects the request and never returns the sentinel
    content.
  5. Create an in-repository symlink to outside.txt and assert that it is also
    rejected.

No real user file or secret is needed to reproduce the defect.

Acceptance criteria

  • Read, list, write, and patch paths are resolved through one shared
    repository-boundary policy.
  • .., absolute-path, prefix-confusion, and symlink escapes are rejected.
  • Normal paths inside the repository continue to work.
  • Tests use temporary sentinel files and never inspect real user secrets.
  • go test ./internal/tools and make verify pass.

Context

GPTCode research initially inferred safety from QUALITY.md, which documents
the intended boundary for research evidence. Direct inspection of
internal/tools/tools.go contradicted that answer. This issue tracks the
executable enforcement required for model-invoked tools.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions