Skip to content

Remote branch name injection

Low
martinvonz published GHSA-gg38-mhjq-j4mp Feb 7, 2025

Package

No package listed

Affected versions

<= 0.25.0

Patched versions

0.26.0

Description

Technical details

When cloning, jj creates a repo-level configuration file (.jj/repo/config.toml) and set the repository level trunk() alias to the default branch name:

[revset-aliases]
"trunk()" = "main@origin"

This behavior was located at the write_repository_level_trunk_alias method.

By controlling the branch name, we tried to mount two following attacks, but none were successful.

Configuration injection

If we can modify the branch name to contain something like: “\n[ui]\ndiff.tool = "malware the configuration will look like:

[revset-aliases]
"trunk()" = "main@origin"
[ui]
diff.tool="malware"

However, we find it is impossible to do so as git expects. We created the branch name with newline, “[“, and “]” characters by modifying the directory structure directly without going through git CLI. Still, libgit2 correctly blocks such cases. Digging deeper into libgit2 implementation, we validated that bypassing this restriction is not possible:

Template injection

We found that we could change the branch name to a valid Revset language template and call various builtin functions, such as, author, files, diff_contains, etc. However, due to the template language being simple and limited, we could not find any practical impact.

Steps to reproduce

  1. Run jj to clone the following repository: https://github.com/khanh-calif/testrepo.git
  2. Verify that the config file testrepo/.jj/repo/config.toml has the following content:
[revset-aliases]
"trunk()" = 'author("khanh")|t@origin'

Recommendations

Due to the Revset language might change and add potential exploitable functions in the future, for defense in depth, we recommend fixing this issue by validating the default remote branch before writing it into the revset-aliases section.

Severity

Low

CVE ID

No known CVE

Weaknesses

No CWEs

Credits