Skip to content

Unauthenticated local-path APIs disclose arbitrary server files #601

Open

Description

@carfeii

Affected versions: confirmed on main at commit d92819a (the project publishes no tagged release).

Summary

Multiple public routes (/codemap/file, /local_repo/structure, /repo/prepare) accept a caller-chosen local filesystem root via repo_url. Repo.is_local treats any value that isn't an http(s)/ftp URL with a host as a trusted local path, and Repo.save_path returned it unchanged with no containment. Selecting repo_url=/ makes any server-readable file reachable: /codemap/file returns its content directly, and /repo/prepare's indexer reads and embeds the whole tree.

Details

# api/repository.py
@property
def is_local(self) -> bool:
    return not _path_is_url(self.repo_url)

@property
def save_path(self) -> str:
    if self.is_local:
        return self.repo_url   # no allowlist at all
    return os.path.join(self.root_path, self.name)
# api/services/codemap.py
def read_repo_file(repo_url, repo_type, file_path):
    repo_dir = os.path.realpath(Repo(repo_url=repo_url, repo_type=repo_type).save_path)
    target = os.path.realpath(os.path.join(repo_dir, file_path))
    if os.path.commonpath([repo_dir, target]) != repo_dir:
        raise ValueError(...)
    ...

Selecting repo_url=/ makes repo_dir resolve to /, so the containment check against repo_dir is a no-op: every absolute path is "within" /.

POC

(available upon request)

Impact

Any unauthenticated caller who can reach the API can read arbitrary server-readable files via GET /codemap/file?repo_url=/&file_path=<any absolute path minus the leading slash>, or have the RAG indexer embed and persist an entire arbitrary directory tree via /repo/prepare.

Suggested fix: require a local repository path to resolve within an operator-owned allowlisted root before any file/structure/indexing operation uses it. A fix is included in the linked PR.

Fix: #594

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions