Patrick Steinhardt' via Git Security 35cb1bb0b9 bundle-uri: fix arbitrary file writes via parameter injection
We fetch bundle URIs via `download_https_uri_to_file()`. The logic to
fetch those bundles is not handled in-process, but we instead use a
separate git-remote-https(1) process that performs the fetch for us. The
information about which file should be downloaded and where that file
should be put gets communicated via stdin of that process via a "get"
request. This "get" request has the form "get $uri $file\n\n". As may be
obvious to the reader, this will cause git-remote-https(1) to download
the URI "$uri" and put it into "$file".

The fact that we are using plain spaces and newlines as separators for
the request arguments means that we have to be extra careful with the
respective vaules of these arguments:

  - If "$uri" contained a space we would interpret this as both URI and
    target location.

  - If either "$uri" or "$file" contained a newline we would interpret
    this as a new command.

But we neither quote the arguments such that any characters with special
meaning would be escaped, nor do we verify that none of these special
characters are contained.

If either the URI or file contains a newline character, we are open to
protocol injection attacks. Likewise, if the URI itself contains a
space, then an attacker-controlled URI can lead to partially-controlled
file writes.

Note that the attacker-controlled URIs do not permit completely
arbitrary file writes, but instead allows an attacker to control the
path in which we will write a temporary (e.g., "tmp_uri_XXXXXX")
file.

The result is twofold:

  - By adding a space in "$uri" we can control where exactly a file will
    be written to, including out-of-repository writes. The final
    location is not completely arbitrary, as the injected string will be
    concatenated with the original "$file" path. Furthermore, the name
    of the bundle will be "tmp_uri_XXXXXX", further restricting what an
    adversary would be able to write.

    Also note that is not possible for the URI to contain a newline
    because we end up in `credential_from_url_1()` before we try to
    issue any requests using that URI. As such, it is not possible to
    inject arbitrary commands via the URI.

  - By adding a newline to "$file" we can inject arbitrary commands.
    This gives us full control over where a specific file will be
    written to. Potential attack vectors would be to overwrite hooks,
    but if an adversary were to guess where the user's home directory is
    located they might also easily write e.g. a "~/.profile" file and
    thus cause arbitrary code execution.

    This injection can only become possible when the adversary has full
    control over the target path where a bundle will be downloaded to.
    While this feels unlikely, it is possible to control this path when
    users perform a recursive clone with a ".gitmodules" file that is
    controlled by the adversary.

Luckily though, the use of bundle URIs is not enabled by default in Git
clients (yet): they have to be enabled by setting the `bundle.heuristic`
config key explicitly. As such, the blast radius of this parameter
injection should overall be quite contained.

Fix the issue by rejecting spaces in the URI and newlines in both the
URI and the file. As explained, it shouldn't be required to also
restrict the use of newlines in the URI, as we would eventually die
anyway in `credential_from_url_1()`. But given that we're only one small
step away from arbitrary code execution, let's rather be safe and
restrict newlines in URIs, as well.

Eventually we should probably refactor the way that Git talks with the
git-remote-https(1) subprocess so that it is less fragile. Until then,
these two restrictions should plug the issue.

Reported-by: David Leadbeater <dgl@dgl.cx>
Based-on-patch-by: David Leadbeater <dgl@dgl.cx>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:09:48 -04:00
2024-11-26 22:14:59 +01:00
2024-11-26 22:14:59 +01:00
2024-11-26 22:14:59 +01:00
2023-11-26 10:07:05 +09:00
2023-11-26 10:07:06 +09:00
2023-11-09 18:56:10 +09:00
2023-10-30 07:09:55 +09:00
2023-12-26 12:04:32 -08:00
2023-12-26 12:04:32 -08:00
2024-01-23 10:40:10 -08:00
2024-11-26 22:14:59 +01:00
2024-11-26 22:14:58 +01:00
2024-04-19 12:38:50 +02:00
2024-04-19 12:38:50 +02:00
2024-04-19 12:38:50 +02:00
2023-08-31 15:51:07 -07:00
2023-11-26 10:07:05 +09:00
2024-11-26 22:14:59 +01:00
2023-11-26 10:07:05 +09:00
2023-12-26 12:04:32 -08:00
2024-04-19 12:38:50 +02:00
2023-12-26 12:04:32 -08:00
2024-04-19 12:38:50 +02:00
2023-11-26 10:07:05 +09:00
2023-11-26 10:07:05 +09:00
2023-11-26 10:07:05 +09:00
2023-11-26 10:07:05 +09:00
2023-10-09 15:55:01 -07:00
2023-10-23 13:56:36 -07:00
2024-04-19 12:38:46 +02:00
2024-04-19 12:38:46 +02:00
2023-11-26 10:07:05 +09:00
2024-04-19 12:38:50 +02:00
2023-12-15 14:08:28 -08:00
2024-11-26 22:14:59 +01:00
2024-04-19 12:38:50 +02:00
2024-04-19 12:38:46 +02:00
2024-04-19 12:38:50 +02:00
2024-04-19 12:38:46 +02:00
2023-11-26 10:07:05 +09:00
2024-11-26 22:14:59 +01:00
2024-11-26 22:14:59 +01:00
2024-04-19 12:38:50 +02:00
2024-04-19 12:38:37 +02:00
2023-11-26 10:07:05 +09:00
2023-11-26 10:07:05 +09:00
2023-11-26 10:07:05 +09:00

Build status

Git - fast, scalable, distributed revision control system

Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals.

Git is an Open Source project covered by the GNU General Public License version 2 (some parts of it are under different licenses, compatible with the GPLv2). It was originally written by Linus Torvalds with help of a group of hackers around the net.

Please read the file INSTALL for installation instructions.

Many Git online resources are accessible from https://git-scm.com/ including full documentation and Git related tools.

See Documentation/gittutorial.txt to get started, then see Documentation/giteveryday.txt for a useful minimum set of commands, and Documentation/git-<commandname>.txt for documentation of each command. If git has been correctly installed, then the tutorial can also be read with man gittutorial or git help tutorial, and the documentation of each command with man git-<commandname> or git help <commandname>.

CVS users may also want to read Documentation/gitcvs-migration.txt (man gitcvs-migration or git help cvs-migration if git is installed).

The user discussion and development of Git take place on the Git mailing list -- everyone is welcome to post bug reports, feature requests, comments and patches to git@vger.kernel.org (read Documentation/SubmittingPatches for instructions on patch submission and Documentation/CodingGuidelines).

Those wishing to help with error message, usage and informational message string translations (localization l10) should see po/README.md (a po file is a Portable Object file that holds the translations).

To subscribe to the list, send an email to git+subscribe@vger.kernel.org (see https://subspace.kernel.org/subscribing.html for details). The mailing list archives are available at https://lore.kernel.org/git/, https://marc.info/?l=git and other archival sites.

Issues which are security relevant should be disclosed privately to the Git Security mailing list git-security@googlegroups.com.

The maintainer frequently sends the "What's cooking" reports that list the current status of various development topics to the mailing list. The discussion following them give a good reference for project status, development direction and remaining tasks.

The name "git" was given by Linus Torvalds when he wrote the very first version. He described the tool as "the stupid content tracker" and the name as (depending on your mood):

  • random three-letter combination that is pronounceable, and not actually used by any common UNIX command. The fact that it is a mispronunciation of "get" may or may not be relevant.
  • stupid. contemptible and despicable. simple. Take your pick from the dictionary of slang.
  • "global information tracker": you're in a good mood, and it actually works for you. Angels sing, and a light suddenly fills the room.
  • "goddamn idiotic truckload of sh*t": when it breaks
Description
No description provided
Readme 635 MiB
Languages
C 50.5%
Shell 38.7%
Perl 4.5%
Tcl 3.2%
Python 0.8%
Other 2.1%