Skip to content

GitRepo.subpath should reject parent traversal paths #3273

@Aphroq

Description

@Aphroq

Please read this first

  • Have you read the docs? Yes.
  • Have you searched for related issues? Yes.

Describe the bug

GitRepo.apply() builds the source copied from the temporary clone by appending subpath to the clone directory. On current main, a subpath containing .. can make the cp -R source leave the cloned repository root.

This means a git_repo artifact with an untrusted or generated subpath can copy files from outside the clone directory into the destination workspace.

Debug information

  • Agents SDK version: main@683b6e7
  • Python version: Python 3.12.1

Repro steps

Run this from the repository root:

import asyncio
import uuid
from pathlib import Path

from agents.sandbox.entries import GitRepo
from agents.sandbox.types import ExecResult


class State:
    session_id = uuid.UUID("00000000-0000-0000-0000-000000000001")
    image = "fake"


class RecordingSession:
    state = State()

    def __init__(self):
        self.exec_calls = []

    async def exec(self, *command, **kwargs):
        self.exec_calls.append(tuple(str(part) for part in command))
        return ExecResult(stdout=b"", stderr=b"", exit_code=0)

    async def mkdir(self, path, *, parents=False, user=None):
        pass


async def main():
    session = RecordingSession()
    repo = GitRepo(repo="openai/example", ref="main", subpath="../../outside")
    await repo.apply(session, Path("/workspace/copied"), Path("/ignored"))
    print([call for call in session.exec_calls if call[:1] == ("cp",)])


asyncio.run(main())

Actual result on current main: the recorded copy command contains a source like:

/tmp/sandbox-git-00000000000000000000000000000001-.../../../outside/.

Expected behavior

GitRepo.subpath should be validated before copying. Empty paths, absolute paths, Windows-style paths, and any path containing a .. component should be rejected before cp runs. Normal relative paths such as docs/reference should continue to work.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions