Update Rust crate gix-path to v0.10.11 [SECURITY] #12
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
0.10.9
->0.10.11
GitHub Vulnerability Alerts
CVE-2024-45305
Summary
gix-path
executesgit
to find the path of a configuration file that belongs to thegit
installation itself, but mistakenly treats the local repository's configuration as system-wide if no higher scoped configuration is found. In rare cases, this causes a less trusted repository to be treated as more trusted, or leaks sensitive information from one repository to another, such as sending credentials to another repository's remote.Details
In
gix_path::env
, the underlying implementation of theinstallation_config
andinstallation_config_prefix
functions callsgit config -l --show-origin
and parses the first line of the output to extract the path to the configuration file holding the configuration variable of highest scope:https:/Byron/gitoxide/blob/12251eb052df30105538fa831e641eea557f13d8/gix-path/src/env/git/mod.rs#L91
https:/Byron/gitoxide/blob/12251eb052df30105538fa831e641eea557f13d8/gix-path/src/env/git/mod.rs#L112
While the configuration variable of highest scope is not usually in the local scope, there are practical situations where this occurs:
GIT_CONFIG_SYSTEM
andGIT_CONFIG_GLOBAL
environment variables to/dev/null
(or toNUL
on Windows). This preventsgix-path
from finding the path of configuration files for those scopes, while not preventing downstream components such as the function ingix-config
from reporting a local path as being associated with the installation.GIT_CONFIG_NOSYSTEM
environment variable can be used to disable configuration associated with the installation. (GIT_CONFIG_NOSYSTEM=1
is more powerful thanGIT_CONFIG_SYSTEM=/dev/null
on systems where an additional "unknown" scope is associated with the installation, as occurs on macOS with Apple Git.) This will cause the local scope to be the highest nonempty scope under even more situations, though in practice it is less dangerous because most, though possibly not all, downstream components would disregard the value.A user may use either or both of the latter two techniques to turn off an undesired configuration or to create a more replicable environment. Such a user would expect that this results in a more controlled configuration.
Often, when located inside one repository, a user performs operations on that repository or that are not specific to any repository. In such use, local configuration is typically desired or at least acceptable, and mistaking it as coming from another scope is not typically harmful.
However, sometimes a user is in one repository and operates on another repository. A major case where this occurs is cloning one repository while located in another. This can be done in an ad-hoc fashion, including when cloning the repository outside of the one we are inside. It may also potentially be automated by an application for purposes such as submodule handling. Two kinds of problems are anticipated:
PoC
In this example, we send mock
Authorization: Basic ...
credentials meant for one repository's remote to another remote, by runninggix
while inside the first repository to clone the second repository.These instructions are written for a Unix shell, but they will work in other shells, including in PowerShell on Windows if the method of setting environment variables is adapted and
/dev/null
is replaced withNUL
. This procedure is likely to demonstrate the problem on all systems except macOS. This is due to the high-scoped "unknown" configuration that usually accompanies Apple Git, and reflects that gix-path is in practice much less vulnerable on macOS (though still potentially vulnerable).Install
dummyhttp
to serve as a local HTTP server for the demonstration.Obtain a build of
gitoxide
with themax
feature set enabled. While this vulnerability affects other builds, this example requiresmax
forhttp.extraHeader
support.Running
cargo install gitoxide
will install such a build though it may build against a patched version ofgix-path
. Cloning the repository (12251eb052df30105538fa831e641eea557f13d8 and earlier are affected) and building withcargo build
orcargo install --path .
are also sufficient. In contrast, installing from published binaries withbinstall
orquickinstall
does not provide themax
feature, as of this writing.Run:
dummyhttp -i 127.0.0.1 -c 403 -v
In a separate terminal, create a new local repository and set up a mock remote and
http.extraHeader
configuration:Make sure the testing setup is working by running
gix fetch
in the repository and checking that it fails in the expected way. In the terminal where that is run, a message should be shown indicating an HTTP 403 error. The more interesting output is in the terminal wheredummyhttp
is running, which should look like this:Some details may differ, especially dates and times. But
Authorization: Basic abcde
should be shown.Now, in the terminal where you ran
gix fetch
, try cloning a separate repository:Check the output appended in the terminal where
dummyhttp
is running. This is to observe thatAuthorization: Basic abcde
was rightly not sent.Alternatively, if it does appear, then your system may be in one of the uncommon configurations that is vulnerable without further action.
Now rerun that command, but with a modified environment, to cause
gix-path
to wrongly treat configuration from the local scope as being associated with thegit
installation:Check the output appended in the terminal where
dummyhttp
is running. Observe thatAuthorization: Basic abcde
was wrongly sent.While this procedure uses the same remote host for both repositories, this is not a required element. If the second repository had a different, untrusted host, the extra header would still be sent.
Impact
It is believed to be very difficult to exploit this vulnerability deliberately, due to the need either to anticipate a situation in which higher-scoped configuration variables would be absent, or to arrange for this to happen. Although any operating system may be affected, users running Apple Git on macOS are much less likely to be affected.
In the example shown above, more secure general practices would avoid it: using a credential manager, or even using
http.<url>.extraHeader
with as specific a<url>
as possible, rather than the more generalhttp.extraHeader
. Many scenarios are analogous: if each repository's configuration is as secure as possible for how the repository is used, and secrets are stored securely and separately, then the circumstances under which an unacceptably unsecure configuration is used, or under which a leak of credentials would occur, become unlikely.CVE-2024-45405
Summary
gix-path
runsgit
to find the path of a configuration file associated with thegit
installation, but improperly resolves paths containing unusual or non-ASCII characters, in rare cases enabling a local attacker to inject configuration leading to code execution.Details
In
gix_path::env
, the underlying implementation of theinstallation_config
andinstallation_config_prefix
functions callsgit config -l --show-origin
to find the path of a file to treat as belonging to thegit
installation.Affected versions of
gix-path
do not pass-z
/--null
to causegit
to report literal paths (650a1b5
). Instead, to cover the occasional case thatgit
outputs a quoted path, they attempt to parse the path by stripping the quotation marks:https:/Byron/gitoxide/blob/1cfe577d461293879e91538dbc4bbfe01722e1e8/gix-path/src/env/git/mod.rs#L138-L142
The problem is that, when a path is quoted, it may change in substantial ways beyond the concatenation of quotation marks. If not reversed, these changes can result in another valid path that is not equivalent to the original.
This is not limited to paths with unusual characters such as quotation marks or newlines. Unless
git
is explicitly configured withcore.quotePath
set tofalse
, it also happens when the path contains most non-ASCII characters, including accented or non-English letters. For example,é
is transformed to\303\251
, with literal backslashes. (This is an octal representation of the bytes in its UTF-8 encoding. This behavior is not limited to systems that encode paths with UTF-8 on disk.)Rarely, the configuration file
gix-path
wrongly attempts to open can be created by an attacker who has a limited user account on the system. The attacker would often need to request an account username tailored to carrying out the attack.PoC
Quick demonstration on Unix
On a Unix-like system in which Git supports no higher scope than
system
for configuration variables (i.e., not on macOS with Apple Git), in a locale that supports UTF-8, withgitoxide
installed, run:If the above conditions are satisfied and the
gix
command was built against an affected version ofgix-path
, then the last command's output looks something like this:Demonstration across user accounts on Windows
On a test system running Windows on which Git for Windows is not installed system-wide—resembling a scenario in which users who wish to use Git are expected to install it themselves for their accounts—create two accounts, with these usernames:
C:\Users\Renée
.C:\Users\Ren
.As Ren, run these commands in PowerShell:
(The
gitconfig
file can instead be written manually, in which case Ren need not havegit
.)As Renée:
Install Git for Windows in the default location for non-systemwide installations, which for that user account is inside
C:\Users\Renée\AppData\Local\Programs
. For a non-administrative installation, Git for Windows will pick this location automatically. Allow the installer to place the directory containinggit
in the user'sPATH
, as it does by default.(The scenario can be modified for any location the attacker can predict. So, for example, Renée can install Git for Windows with
scoop
, and Ren could carry out the attack with correspondingly modified path components in place ofAppData\Local\Programs\Git
.)Install
gitoxide
using any common technique, such as by installing Rust and then runningcargo install gitoxide
.Open a PowerShell window and run a
gix
command that attempts to run the SSH client for transport. For example:At least one, and usually two, instances of the Windows calculator will pop up. This happens because
calc.exe
was configured in the fake configuration file the user Ren was able to cause to be used, by placing it at the locationgix-path
wrongly resolved the path of Renée's own configuration file to.The
gitconfig
file written by the attacker can be adjusted with an arbitrary choice of payload, or to set other configuration variables.Impact
On a single-user system, it is not possible to exploit this, unless
GIT_CONFIG_SYSTEM
andGIT_CONFIG_GLOBAL
have been set to unusual values or Git has been installed in an unusual way. Such a scenario is not expected.Exploitation is unlikely even on a multi-user system, though it is plausible in some uncommon configurations or use cases. It is especially unlikely with Apple Git on macOS, due to its very high scoped configuration in
/Library
or/Applications
that would be detected instead, as in CVE-2024-45305.The likelihood of exploitation may be higher on Windows, where attacks such as those shown in the Windows proof-of-concept above can be performed due to the status of
\
as a directory separator, and where there is no restriction on usernames containing accented or non-English letters (though the latter is also permitted on some other systems). Even then, complex user interaction is required. In most cases, a system administrator would have to approve an innocuous-seeming username, and then the targeted user (who could be the same or a different user) would have to use an application that usesgix-path
.In general, exploitation is more likely to succeed if at least one of the following applies:
git
themselves, and are likely to do so in predictable locations.git
is installed, whether due to usernames in their paths or otherwise, contain characters thatgit
quotes by default in paths, such as non-English letters and accented letters.system
-scope configuration file is specified with theGIT_CONFIG_SYSTEM
environment variable, and its path is in an unusual location or has strangely named components.system
-scope configuration file is absent, empty, or suppressed by means other thanGIT_CONFIG_NOSYSTEM
. Currently,gix-path
can treat aglobal
-scope configuration file as belonging to the installation if no higher scope configuration file is available. This increases the likelihood of exploitation even on a system wheregit
is installed system-wide in an ordinary way.However, exploitation is expected to be very difficult even under any combination of those factors.
Although the effect here is similar to CVE-2022-24765 once exploited, a greater degree of user interaction would usually be required, and the attack complexity here is much higher because the necessary conditions are uncommon and challenging to predict.
Release Notes
Byron/gitoxide (gix-path)
v0.10.11
: gix-path v0.10.11Compare Source
Bug Fixes
Don't require usable temp dir to get installation config
When running
git config -l ...
to find the configuration filepath associated with the
git
installation itself, the currentworking directory for the subprocess was set to the current
directory prior to #1523, and to
/tmp
or a/tmp
-like directorysince #1523 (which improved performance and security).
This builds on #1523, as well as on subsequent changes to run
git
in a way that its behavior depends less on its CWD, by making an
even more robust choice of CWD for the subprocess, so that the CWD
is less likely to be deeply nested or on network storage; more
likely to exist; and, on Unix-like systems, less likely to contain
a
.git
entry (though agit
with security updates should refuseto take any configuration from such a repository unless it is owned
by the user).
Due to a combination of other measures that harden against
malicious or unusual contents (especially setting
GIT_DIR
), themost significant benefit of this change is to fix the problem that
a nonexistent temp dir would prevent the command from succeeding.
The main way that could happen is if
TMPDIR
on Unix-like systems,or
TMP
orTEMP
on Windows, is set to an incorrect value.Because these variables are sometimes reasonable to customize for
specific purposes, it is plausible for them to be set to incorrect
values by accident.
Except on Windows, this always uses
/
as the CWD for thesubprocess.
On Windows, we use the Windows directory (usually
C:\Windows
)rather than the root of the system drive (usually
C:\
), because:variables, and it is possible for our own parent process to pass
down an overly sanitized environment.
Although this can be so sanitized we cannot find the Windows
directory, this is less likely to occur than being unable to find
the root of the system drive.
This due to moderately broad awareness that the
SystemRoot
environment variable (which, somewhat confusingly, holds the path
of the Windows directory, not the root of the system drive)
should be preserved even when clearing most other variables.
Some libraries will even automatically preserve
SystemRoot
whenclearing others or restore it. For example:
Under the current behavior of
env::temp_dir()
, which is now afallback if we cannot determine the Windows directory, we already
fall back to the Windows directory evenutally, if temp dir
related environment variables are also unset.
This is because
env::temp_dir()
usually callsGetTempDir2
inthe Windows API, which implements that fallback behavior (after
first trying the user's user profile directory).
Avoiding adding yet another place to fall back to that would not
otherwise be attempted slightly decreases behavioral complexity,
and there is no reason to think a directory like
C:\
would workwhen a directory like
C:\Windows
doesn't.The root of the system drive on a Windows system usually permits
limited user accounts to create new directories there, so a
directory like
C:\
on Windows actually has most of thedisadvantages of a location like
/tmp
on a Unix-like system.This is actually a much less significant reason to prefer a
directory like
C:\Windows
to a directory likeC:\
than itmight seem. After all, if
C:\.git
exists and andgit
uses itwhen run from
C:\
, thengit
would usually also use it whenrun from
C:\Windows
(and from numerous other locations)!However, the reason there is still a small reason to prefer a
location like
C:\Windows
to a location likeC:\
is that, if asystem has a vulnerable
git
but a user or system administratorhas sought to work around it by listing
C:\
inGIT_CEILING_DIRECTORIES
, then that may keepgit
fromtraversing upward into
C:\
, but it would not keepC:\
frombeing used if that is where we already are.
An even more significant reason this motivation is a minor one is
that the other measures we are taking, including setting
GIT_DIR
, should be sufficient to avoid at least the securitydimension of the problem, which arises from actually using the
configuration from a repo that is discovered.
The user profile directory may be more deeply nested.
The user profile directory may sometimes be on slow network
storage when the discovered Windows directory is not.
In some situations, the user profile directory does not actually
exist, or does not exist yet.
Overly sanitized environments are more likely to lack the
USERPROFILE
vairable than theSystemRoot
variable.Users may occasionally choose to have their entire user profile
directory be a Git repository.
It's no easier to avoid the problem of using
C:\.git
in a userprofile directory than in
C:\Windows
: they're usually both underC:\
, and are both not the same asC:\
. (If the user profiledirectory is a repository, then that will avoid that problem, yet
be its own problem, if not for other measures that prevent both.)
If the
git
command is an old and unpatched vulnerable versionin which
safe.directory
is not yet implemented, or in whichGHSA-j342-m5hw-rr3v
or other vulnerabilities where
git
would perform operations onuntrusted local repositories owned by other users are unpatched,
then a
.git
subdirectory of a shared/tmp
or/tmp
-likedirectory could be created by another account, and its local
configuration would still have been used. (This is not a bug in
gitoxide per se; having vulnerable software installed that other
software may use is inherently insecure. But it is nice to offer
a small amount of protection against this when readily feasible.)
If the
/tmp
-like location is a Git repository owned by thecurrent user, then its local configuration would have been used.
https:/dotnet/docs/issues/41193
https:/python/cpython/pull/95486#issuecomment-1881469554
https:/python/cpython/pull/95486#issuecomment-1882134234
Parsing is more reliable for paths containing unusual characters,
because
-z
/--null
causes all paths to be output literally.Previously,
"
characters were trimmed from the ends, but thiswould not always extract a correct path, because when a path
contains characters that cause
git
to enclose it in doublequotes, those characters are usually represented in a symbolic
form, usually with
\
escapes.In some scenarios, such as usually on Windows when the escaped
character is itself a
\
and not in the leading position, themangled path would be usable, but more often it would not.
The volume of output is less, because
--name-only
casues valuesnot to be included in the output.
The combination of
-z
/--null
and--name-only
makes theoutput format simpler, and the parsing logic is accordingly
simpler.
Commit Statistics
Commit Details
view details
c759819
)3cf9694
)GIT_HIGHEST_SCOPE_CONFIG_PATH
(0672576
)adbaa2a
)EXE_INFO
to something that probably captures its contents better. (dd2d666
)cargo fmt
(b11f7db
)EXE_NAME
aconst
too (fb0b6d8
)NULL_DEVICE
aconst
, rather than astatic
item (9917d47
)first_file_from_config_with_origin
test with related ones (57e9a6f
)7cd20bb
)dd65e7b
)exe_info
tests (5ac5f74
)git
from (5200184
)6160a83
)2bce0d2
)073e277
)4e936bc
)8f6d39d
)b827813
)git
from a different directory (7fa5e35
)598c487
)os::windows
error on non-Windows (1305114
)ab0dcc1
)8472447
)f70b904
)--system
(29c6cca
)--show-scope
(f35e44c
)15e7b67
)c80d562
)e60540f
)56dab13
)5c1b4c0
)env::temp_dir()
in both tests that set temp vars (79af259
)703f882
)60465a5
)9641660
)5723077
)7280a2d
)env::temp_dir()
as desired (15cec4e
)744bb38
)287f267
)65d5151
)49e0715
)fd065ac
)5a300e6
)1ee98bf
)ccd0401
)de2f35f
)650a1b5
)9df57aa
)649f588
)beba720
)37ba461
)2e0ce50
)f992fb7
)ec69c88
)v0.10.10
: gix-path v0.10.10Compare Source
A maintenance release without user-facing changes.
Commit Statistics
Commit Details
view details
0f25841
)83c9de0
)--system
fromgit config
call as it fails on MacOS (6b1c243
)git config -l
in temp dir when looking up system config (20ef4e9
)e2c747d
)087594c
)Configuration
📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.