Skip to content

Unvalidated PR/repo branch refs reach git as options (arbitrary file write via PR diff) #378

Description

@beardthelion

Summary

create_pr stores the PR's source_branch and target_branch from the request body without validating them as git refs. Both are later interpolated into a single git argv element, so a branch name beginning with - is parsed by git as an option rather than a revision. A target_branch of --output=<path> turns the PR diff endpoint into an arbitrary file write with the node process's privileges.

Impact

GET /api/v1/repos/{owner}/{repo}/pulls/{n}/diff builds git diff {target}...{source} as one argument (branch_diff_names / branch_diff in crates/gitlawb-node/src/git/store.rs). With target_branch = --output=/tmp/x, git runs git diff --output=/tmp/x...{source} and writes to that path. The same shape reaches git worktree add _merge_worktree {target} and git merge --no-ff {source} in merge_branch.

Reachability: opening the PR needs read access (create_pr gates on authorize_repo_read), but the diff endpoint takes an optional identity, so on a public repo the trigger is unauthenticated. The withhold check that builds the diff runs before the per-path visibility gate, so the write happens even when the request ends in a denial or a 500.

Confirmed by reproduction against the real handlers: an anonymous GET .../pulls/1/diff on a public repo, after a reader opened a PR with an --output= target, created the attacker-named file on disk.

Fix

Validate branch refs at the create_pr storage boundary (the single point both sink families read from) against git check-ref-format rules, rejecting a leading - as the security-critical case. A -- delimiter is not the fix: {target}...{source} is a revision argument, and -- there reinterprets the revision as a pathspec.

Metadata

Metadata

Assignees

No one assigned

    Labels

    crate:nodegitlawb-node — the serving node and REST APIkind:securityVulnerability fix or hardeningsev:highMajor break or real security/trust risk, no easy workaroundsubsystem:apiNode REST API request/response surface

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions