From 69cfd1068e3cafa4db14e791122837c1d2f7e1ef Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 8 Jul 2024 10:07:56 -0500 Subject: [PATCH] Advisory for CVE-2024-35186 in gix-fs, gix-index, gix-worktree (#1996) --- crates/gix-fs/RUSTSEC-0000-0000.md | 87 ++++++++++++++++++++++++ crates/gix-index/RUSTSEC-0000-0000.md | 87 ++++++++++++++++++++++++ crates/gix-worktree/RUSTSEC-0000-0000.md | 87 ++++++++++++++++++++++++ 3 files changed, 261 insertions(+) create mode 100644 crates/gix-fs/RUSTSEC-0000-0000.md create mode 100644 crates/gix-index/RUSTSEC-0000-0000.md create mode 100644 crates/gix-worktree/RUSTSEC-0000-0000.md diff --git a/crates/gix-fs/RUSTSEC-0000-0000.md b/crates/gix-fs/RUSTSEC-0000-0000.md new file mode 100644 index 00000000..94d44d06 --- /dev/null +++ b/crates/gix-fs/RUSTSEC-0000-0000.md @@ -0,0 +1,87 @@ +```toml +[advisory] +id = "RUSTSEC-0000-0000" +package = "gix-fs" +date = "2024-05-22" +url = "https://github.com/Byron/gitoxide/security/advisories/GHSA-7w47-3wg8-547c" +references = [ + "https://github.com/advisories/GHSA-7w47-3wg8-547c", + "https://nvd.nist.gov/vuln/detail/CVE-2024-35186", +] +categories = ["code-execution"] +cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H" +keywords = ["directory-traversal"] +aliases = ["CVE-2024-35186", "GHSA-7w47-3wg8-547c"] +license = "CC0-1.0" + +[versions] +patched = [">= 0.11.0"] +``` + +# Traversal outside working tree enables arbitrary code execution + +### Summary + +During checkout, gitoxide does not verify that paths point to locations in the working tree. A specially crafted repository can, when cloned, place new files anywhere writable by the application. + +### Details + +Although `gix-worktree-state` checks for collisions with existing files, it does not itself check if a path is really in the working tree when performing a checkout, nor do the path checks in `gix-fs` and `gix-worktree` prevent this. Cloning an untrusted repository containing specially crafted tree or blob names will create new files outside the repository, or inside the repository or a submodule's `.git` directory. The simplest cases are: + +- A tree named `..` to traverse upward. This facilitates arbitrary code execution because files can be placed in one or more locations where they are likely to be executed soon. +- A tree named `.git` to enter a `.git` directory. This facilitates arbitrary code execution because hooks can be installed. + +A number of alternatives that achieve the same effect are also possible, some of which correspond to specific vulnerabilities that have affected Git in the past: + +- A tree or blob whose name contains one or more `/`, to traverse upward or downward. For example, even without containing any tree named `..` or `.git`, a repository can represent a file named `../outside` or `.git/hooks/pre-commit`. This is distinct from the more intuitive case a repository containing trees that represent those paths. +- In Windows, a tree or blob whose name contains one or more `\`, to traverse upward or downward. (Unlike `/`, these are valid on other systems.) See [GHSA-xjx4-8694-q2fq](https://github.com/git/git/security/advisories/GHSA-xjx4-8694-q2fq). +- On a case-insensitive filesystem (such as NTFS, APFS, or HFS+), a tree named as a case variant of `.git`. +- On HFS+, a tree named like `.git` or a case variant, with characters added that HFS+ ignores [in collation](https://developer.apple.com/library/archive/technotes/tn/tn1150.html#StringComparisonAlgorithm). See https://github.com/git/git/commit/6162a1d323d24fd8cbbb1a6145a91fb849b2568f. +- On NTFS, a tree equivalent to `.git` (or a case variant) by the use of [NTFS stream](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/c54dec26-1551-4d3a-a0ea-4fa40f848eb3) notation, such as `.git::$INDEX_ALLOCATION`. See [GHSA-5wph-8frv-58vj](https://github.com/git/git/security/advisories/GHSA-5wph-8frv-58vj). +- On an NTFS volume with [8.3 aliasing](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#short-vs-long-names) enabled, a tree named as `git~1` (or a case variant). See [GHSA-589j-mmg9-733v](https://github.com/git/git/security/advisories/GHSA-589j-mmg9-733v). + +When a checkout creates some files outside the repository directory but fails to complete, the repository directory is usually removed, but the outside files remain. + +### PoC + +For simplicity, these examples stage a stand-in file with a valid name, modify the index, and commit. The instructions assume `sed` supports `-i`, which is the case on most systems. If using Windows, a Git Bash shell should be used. + +#### Example: Downward traversal to install hooks + +1. Create a new repository with `git init dangerous-repo-installs-hook` and `cd` into the directory. +2. Create the stand-in called `.git@hooks@pre-commit`, with the *contents*: + ```sh + #!/bin/sh + printf 'Vulnerable!\n' + date >vulnerable + ``` +3. Stage the stand-in: `git add --chmod=+x .git@hooks@pre-commit` +4. Edit the index: `env LC_ALL=C sed -i.orig 's|\.git@hooks@pre-commit|.git/hooks/pre-commit|' .git/index` +5. Commit: `git commit -m 'Initial commit'` +6. *Optionally*, push to a private remote. + +Then, on another or the same machine: + +1. Clone the repository with a `gix clone …` command. +2. Enter the newly created directory. +3. *Optionally* run `ls -l .git/hooks` to observe that the `pre-commit` hook is already present. +4. Make a new file and commit it with `git`. This causes the payload surreptitiously installed as a `pre-commit` hook to run, printing the message `Vulnerable!` and creating a file in the current directory containing the current date and time. + +Note that the effect is not limited to modifying the current directory. The payload could be written to perform any action that the user who runs `git commit` is capable of. + +#### Example: Upward traversal to create a file above the working tree + +1. Create a new repository with `git init dangerous-repo-reaches-up`, and `cd` into the directory. +2. Create the stand-in: `echo 'A file outside the working tree, somehow.' >..@outside` +3. Stage the stand-in: `git add ..@outside` +4. Edit the index: `env LC_ALL=C sed -i.orig 's|\.\.@outside|../outside|' .git/index` +5. Commit: `git commit -m 'Initial commit'` +6. *Optionally*, push to a private remote. + +Then, as above, on the same or another machine, clone the repository with a `gix clone …` command. Observe that a file named `outside` is present alongside (not inside) the cloned directory. + +### Impact + +Any use of `gix` or another application that makes use of `gix-worktree-state`, or otherwise relies on `gix-fs` and `gix-worktree` for validation, is affected, if used to clone untrusted repositories. The above description focuses on code execution, as that leads to a complete loss of confidentiality, integrity, and availability, but creating files outside a working tree without attempting to execute code can directly impact integrity as well. + +In use cases where no untrusted repository is ever cloned, this vulnerability has no impact. Furthermore, the impact of this vulnerability *may* be lower when `gix` is used to clone a repository for CI/CD purposes, even if untrusted, since in such uses the environment is usually isolated and arbitrary code is usually run deliberately from the repository with necessary safeguards in place. diff --git a/crates/gix-index/RUSTSEC-0000-0000.md b/crates/gix-index/RUSTSEC-0000-0000.md new file mode 100644 index 00000000..2a4b3217 --- /dev/null +++ b/crates/gix-index/RUSTSEC-0000-0000.md @@ -0,0 +1,87 @@ +```toml +[advisory] +id = "RUSTSEC-0000-0000" +package = "gix-index" +date = "2024-05-22" +url = "https://github.com/Byron/gitoxide/security/advisories/GHSA-7w47-3wg8-547c" +references = [ + "https://github.com/advisories/GHSA-7w47-3wg8-547c", + "https://nvd.nist.gov/vuln/detail/CVE-2024-35186", +] +categories = ["code-execution"] +cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H" +keywords = ["directory-traversal"] +aliases = ["CVE-2024-35186", "GHSA-7w47-3wg8-547c"] +license = "CC0-1.0" + +[versions] +patched = [">= 0.33.0"] +``` + +# Traversal outside working tree enables arbitrary code execution + +### Summary + +During checkout, gitoxide does not verify that paths point to locations in the working tree. A specially crafted repository can, when cloned, place new files anywhere writable by the application. + +### Details + +Although `gix-worktree-state` checks for collisions with existing files, it does not itself check if a path is really in the working tree when performing a checkout, nor do the path checks in `gix-fs` and `gix-worktree` prevent this. Cloning an untrusted repository containing specially crafted tree or blob names will create new files outside the repository, or inside the repository or a submodule's `.git` directory. The simplest cases are: + +- A tree named `..` to traverse upward. This facilitates arbitrary code execution because files can be placed in one or more locations where they are likely to be executed soon. +- A tree named `.git` to enter a `.git` directory. This facilitates arbitrary code execution because hooks can be installed. + +A number of alternatives that achieve the same effect are also possible, some of which correspond to specific vulnerabilities that have affected Git in the past: + +- A tree or blob whose name contains one or more `/`, to traverse upward or downward. For example, even without containing any tree named `..` or `.git`, a repository can represent a file named `../outside` or `.git/hooks/pre-commit`. This is distinct from the more intuitive case a repository containing trees that represent those paths. +- In Windows, a tree or blob whose name contains one or more `\`, to traverse upward or downward. (Unlike `/`, these are valid on other systems.) See [GHSA-xjx4-8694-q2fq](https://github.com/git/git/security/advisories/GHSA-xjx4-8694-q2fq). +- On a case-insensitive filesystem (such as NTFS, APFS, or HFS+), a tree named as a case variant of `.git`. +- On HFS+, a tree named like `.git` or a case variant, with characters added that HFS+ ignores [in collation](https://developer.apple.com/library/archive/technotes/tn/tn1150.html#StringComparisonAlgorithm). See https://github.com/git/git/commit/6162a1d323d24fd8cbbb1a6145a91fb849b2568f. +- On NTFS, a tree equivalent to `.git` (or a case variant) by the use of [NTFS stream](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/c54dec26-1551-4d3a-a0ea-4fa40f848eb3) notation, such as `.git::$INDEX_ALLOCATION`. See [GHSA-5wph-8frv-58vj](https://github.com/git/git/security/advisories/GHSA-5wph-8frv-58vj). +- On an NTFS volume with [8.3 aliasing](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#short-vs-long-names) enabled, a tree named as `git~1` (or a case variant). See [GHSA-589j-mmg9-733v](https://github.com/git/git/security/advisories/GHSA-589j-mmg9-733v). + +When a checkout creates some files outside the repository directory but fails to complete, the repository directory is usually removed, but the outside files remain. + +### PoC + +For simplicity, these examples stage a stand-in file with a valid name, modify the index, and commit. The instructions assume `sed` supports `-i`, which is the case on most systems. If using Windows, a Git Bash shell should be used. + +#### Example: Downward traversal to install hooks + +1. Create a new repository with `git init dangerous-repo-installs-hook` and `cd` into the directory. +2. Create the stand-in called `.git@hooks@pre-commit`, with the *contents*: + ```sh + #!/bin/sh + printf 'Vulnerable!\n' + date >vulnerable + ``` +3. Stage the stand-in: `git add --chmod=+x .git@hooks@pre-commit` +4. Edit the index: `env LC_ALL=C sed -i.orig 's|\.git@hooks@pre-commit|.git/hooks/pre-commit|' .git/index` +5. Commit: `git commit -m 'Initial commit'` +6. *Optionally*, push to a private remote. + +Then, on another or the same machine: + +1. Clone the repository with a `gix clone …` command. +2. Enter the newly created directory. +3. *Optionally* run `ls -l .git/hooks` to observe that the `pre-commit` hook is already present. +4. Make a new file and commit it with `git`. This causes the payload surreptitiously installed as a `pre-commit` hook to run, printing the message `Vulnerable!` and creating a file in the current directory containing the current date and time. + +Note that the effect is not limited to modifying the current directory. The payload could be written to perform any action that the user who runs `git commit` is capable of. + +#### Example: Upward traversal to create a file above the working tree + +1. Create a new repository with `git init dangerous-repo-reaches-up`, and `cd` into the directory. +2. Create the stand-in: `echo 'A file outside the working tree, somehow.' >..@outside` +3. Stage the stand-in: `git add ..@outside` +4. Edit the index: `env LC_ALL=C sed -i.orig 's|\.\.@outside|../outside|' .git/index` +5. Commit: `git commit -m 'Initial commit'` +6. *Optionally*, push to a private remote. + +Then, as above, on the same or another machine, clone the repository with a `gix clone …` command. Observe that a file named `outside` is present alongside (not inside) the cloned directory. + +### Impact + +Any use of `gix` or another application that makes use of `gix-worktree-state`, or otherwise relies on `gix-fs` and `gix-worktree` for validation, is affected, if used to clone untrusted repositories. The above description focuses on code execution, as that leads to a complete loss of confidentiality, integrity, and availability, but creating files outside a working tree without attempting to execute code can directly impact integrity as well. + +In use cases where no untrusted repository is ever cloned, this vulnerability has no impact. Furthermore, the impact of this vulnerability *may* be lower when `gix` is used to clone a repository for CI/CD purposes, even if untrusted, since in such uses the environment is usually isolated and arbitrary code is usually run deliberately from the repository with necessary safeguards in place. diff --git a/crates/gix-worktree/RUSTSEC-0000-0000.md b/crates/gix-worktree/RUSTSEC-0000-0000.md new file mode 100644 index 00000000..756936ed --- /dev/null +++ b/crates/gix-worktree/RUSTSEC-0000-0000.md @@ -0,0 +1,87 @@ +```toml +[advisory] +id = "RUSTSEC-0000-0000" +package = "gix-worktree" +date = "2024-05-22" +url = "https://github.com/Byron/gitoxide/security/advisories/GHSA-7w47-3wg8-547c" +references = [ + "https://github.com/advisories/GHSA-7w47-3wg8-547c", + "https://nvd.nist.gov/vuln/detail/CVE-2024-35186", +] +categories = ["code-execution"] +cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H" +keywords = ["directory-traversal"] +aliases = ["CVE-2024-35186", "GHSA-7w47-3wg8-547c"] +license = "CC0-1.0" + +[versions] +patched = [">= 0.34.0"] +``` + +# Traversal outside working tree enables arbitrary code execution + +### Summary + +During checkout, gitoxide does not verify that paths point to locations in the working tree. A specially crafted repository can, when cloned, place new files anywhere writable by the application. + +### Details + +Although `gix-worktree-state` checks for collisions with existing files, it does not itself check if a path is really in the working tree when performing a checkout, nor do the path checks in `gix-fs` and `gix-worktree` prevent this. Cloning an untrusted repository containing specially crafted tree or blob names will create new files outside the repository, or inside the repository or a submodule's `.git` directory. The simplest cases are: + +- A tree named `..` to traverse upward. This facilitates arbitrary code execution because files can be placed in one or more locations where they are likely to be executed soon. +- A tree named `.git` to enter a `.git` directory. This facilitates arbitrary code execution because hooks can be installed. + +A number of alternatives that achieve the same effect are also possible, some of which correspond to specific vulnerabilities that have affected Git in the past: + +- A tree or blob whose name contains one or more `/`, to traverse upward or downward. For example, even without containing any tree named `..` or `.git`, a repository can represent a file named `../outside` or `.git/hooks/pre-commit`. This is distinct from the more intuitive case a repository containing trees that represent those paths. +- In Windows, a tree or blob whose name contains one or more `\`, to traverse upward or downward. (Unlike `/`, these are valid on other systems.) See [GHSA-xjx4-8694-q2fq](https://github.com/git/git/security/advisories/GHSA-xjx4-8694-q2fq). +- On a case-insensitive filesystem (such as NTFS, APFS, or HFS+), a tree named as a case variant of `.git`. +- On HFS+, a tree named like `.git` or a case variant, with characters added that HFS+ ignores [in collation](https://developer.apple.com/library/archive/technotes/tn/tn1150.html#StringComparisonAlgorithm). See https://github.com/git/git/commit/6162a1d323d24fd8cbbb1a6145a91fb849b2568f. +- On NTFS, a tree equivalent to `.git` (or a case variant) by the use of [NTFS stream](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/c54dec26-1551-4d3a-a0ea-4fa40f848eb3) notation, such as `.git::$INDEX_ALLOCATION`. See [GHSA-5wph-8frv-58vj](https://github.com/git/git/security/advisories/GHSA-5wph-8frv-58vj). +- On an NTFS volume with [8.3 aliasing](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#short-vs-long-names) enabled, a tree named as `git~1` (or a case variant). See [GHSA-589j-mmg9-733v](https://github.com/git/git/security/advisories/GHSA-589j-mmg9-733v). + +When a checkout creates some files outside the repository directory but fails to complete, the repository directory is usually removed, but the outside files remain. + +### PoC + +For simplicity, these examples stage a stand-in file with a valid name, modify the index, and commit. The instructions assume `sed` supports `-i`, which is the case on most systems. If using Windows, a Git Bash shell should be used. + +#### Example: Downward traversal to install hooks + +1. Create a new repository with `git init dangerous-repo-installs-hook` and `cd` into the directory. +2. Create the stand-in called `.git@hooks@pre-commit`, with the *contents*: + ```sh + #!/bin/sh + printf 'Vulnerable!\n' + date >vulnerable + ``` +3. Stage the stand-in: `git add --chmod=+x .git@hooks@pre-commit` +4. Edit the index: `env LC_ALL=C sed -i.orig 's|\.git@hooks@pre-commit|.git/hooks/pre-commit|' .git/index` +5. Commit: `git commit -m 'Initial commit'` +6. *Optionally*, push to a private remote. + +Then, on another or the same machine: + +1. Clone the repository with a `gix clone …` command. +2. Enter the newly created directory. +3. *Optionally* run `ls -l .git/hooks` to observe that the `pre-commit` hook is already present. +4. Make a new file and commit it with `git`. This causes the payload surreptitiously installed as a `pre-commit` hook to run, printing the message `Vulnerable!` and creating a file in the current directory containing the current date and time. + +Note that the effect is not limited to modifying the current directory. The payload could be written to perform any action that the user who runs `git commit` is capable of. + +#### Example: Upward traversal to create a file above the working tree + +1. Create a new repository with `git init dangerous-repo-reaches-up`, and `cd` into the directory. +2. Create the stand-in: `echo 'A file outside the working tree, somehow.' >..@outside` +3. Stage the stand-in: `git add ..@outside` +4. Edit the index: `env LC_ALL=C sed -i.orig 's|\.\.@outside|../outside|' .git/index` +5. Commit: `git commit -m 'Initial commit'` +6. *Optionally*, push to a private remote. + +Then, as above, on the same or another machine, clone the repository with a `gix clone …` command. Observe that a file named `outside` is present alongside (not inside) the cloned directory. + +### Impact + +Any use of `gix` or another application that makes use of `gix-worktree-state`, or otherwise relies on `gix-fs` and `gix-worktree` for validation, is affected, if used to clone untrusted repositories. The above description focuses on code execution, as that leads to a complete loss of confidentiality, integrity, and availability, but creating files outside a working tree without attempting to execute code can directly impact integrity as well. + +In use cases where no untrusted repository is ever cloned, this vulnerability has no impact. Furthermore, the impact of this vulnerability *may* be lower when `gix` is used to clone a repository for CI/CD purposes, even if untrusted, since in such uses the environment is usually isolated and arbitrary code is usually run deliberately from the repository with necessary safeguards in place.