Fix CVE-2024-52005
(cherry picked from commit f18ec62789fa2e3b713d4e488968cf0d1b4f1606)
This commit is contained in:
parent
32f1379e74
commit
82c376fb9b
388
backport-CVE-2024-52005.patch
Normal file
388
backport-CVE-2024-52005.patch
Normal file
@ -0,0 +1,388 @@
|
||||
From 5b257412e25ad29410c389300324886aa59e1f83 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Wed, 6 Nov 2024 20:34:50 +0100
|
||||
Subject: [PATCH 1/3] sideband: mask control characters
|
||||
|
||||
The output of `git clone` is a vital component for understanding what
|
||||
has happened when things go wrong. However, these logs are partially
|
||||
under the control of the remote server (via the "sideband", which
|
||||
typically contains what the remote `git pack-objects` process sends to
|
||||
`stderr`), and is currently not sanitized by Git.
|
||||
|
||||
This makes Git susceptible to ANSI escape sequence injection (see
|
||||
CWE-150, https://cwe.mitre.org/data/definitions/150.html), which allows
|
||||
attackers to corrupt terminal state, to hide information, and even to
|
||||
insert characters into the input buffer (i.e. as if the user had typed
|
||||
those characters).
|
||||
|
||||
To plug this vulnerability, disallow any control character in the
|
||||
sideband, replacing them instead with the common `^<letter/symbol>`
|
||||
(e.g. `^[` for `\x1b`, `^A` for `\x01`).
|
||||
|
||||
There is likely a need for more fine-grained controls instead of using a
|
||||
"heavy hammer" like this, which will be introduced subsequently.
|
||||
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
---
|
||||
sideband.c | 17 +++++++++++++++--
|
||||
t/t5409-colorize-remote-messages.sh | 12 ++++++++++++
|
||||
2 files changed, 27 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sideband.c b/sideband.c
|
||||
index 85bddfdcd4f57a..9384cb02d56a04 100644
|
||||
--- a/sideband.c
|
||||
+++ b/sideband.c
|
||||
@@ -61,6 +61,19 @@ void list_config_color_sideband_slots(struct string_list *list, const char *pref
|
||||
list_config_item(list, prefix, keywords[i].keyword);
|
||||
}
|
||||
|
||||
+static void strbuf_add_sanitized(struct strbuf *dest, const char *src, int n)
|
||||
+{
|
||||
+ strbuf_grow(dest, n);
|
||||
+ for (; n && *src; src++, n--) {
|
||||
+ if (!iscntrl(*src) || *src == '\t' || *src == '\n')
|
||||
+ strbuf_addch(dest, *src);
|
||||
+ else {
|
||||
+ strbuf_addch(dest, '^');
|
||||
+ strbuf_addch(dest, 0x40 + *src);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Optionally highlight one keyword in remote output if it appears at the start
|
||||
* of the line. This should be called for a single line only, which is
|
||||
@@ -73,7 +86,7 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
|
||||
int i;
|
||||
|
||||
if (!want_color_stderr(use_sideband_colors())) {
|
||||
- strbuf_add(dest, src, n);
|
||||
+ strbuf_add_sanitized(dest, src, n);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,7 +119,7 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
|
||||
}
|
||||
}
|
||||
|
||||
- strbuf_add(dest, src, n);
|
||||
+ strbuf_add_sanitized(dest, src, n);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/t/t5409-colorize-remote-messages.sh b/t/t5409-colorize-remote-messages.sh
|
||||
index fa5de4500a4f50..6a6e0d15b21050 100755
|
||||
--- a/t/t5409-colorize-remote-messages.sh
|
||||
+++ b/t/t5409-colorize-remote-messages.sh
|
||||
@@ -98,4 +98,16 @@ test_expect_success 'fallback to color.ui' '
|
||||
grep "<BOLD;RED>error<RESET>: error" decoded
|
||||
'
|
||||
|
||||
+test_expect_success 'disallow (color) control sequences in sideband' '
|
||||
+ write_script .git/color-me-surprised <<-\EOF &&
|
||||
+ printf "error: Have you \\033[31mread\\033[m this?\\n" >&2
|
||||
+ exec "$@"
|
||||
+ EOF
|
||||
+ test_config_global uploadPack.packObjectshook ./color-me-surprised &&
|
||||
+ test_commit need-at-least-one-commit &&
|
||||
+ git clone --no-local . throw-away 2>stderr &&
|
||||
+ test_decode_color <stderr >decoded &&
|
||||
+ test_i18ngrep ! RED decoded
|
||||
+'
|
||||
+
|
||||
test_done
|
||||
|
||||
From a8c289b0a531d25336a96eaa5e3584414ed4c6c4 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Wed, 6 Nov 2024 21:07:51 +0100
|
||||
Subject: [PATCH 2/3] sideband: introduce an "escape hatch" to allow control
|
||||
characters
|
||||
|
||||
The preceding commit fixed the vulnerability whereas sideband messages
|
||||
(that are under the control of the remote server) could contain ANSI
|
||||
escape sequences that would be sent to the terminal verbatim.
|
||||
|
||||
However, this fix may not be desirable under all circumstances, e.g.
|
||||
when remote servers deliberately add coloring to their messages to
|
||||
increase their urgency.
|
||||
|
||||
To help with those use cases, give users a way to opt-out of the
|
||||
protections: `sideband.allowControlCharacters`.
|
||||
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
---
|
||||
Documentation/config.txt | 2 ++
|
||||
Documentation/config/sideband.txt | 5 +++++
|
||||
sideband.c | 10 ++++++++++
|
||||
t/t5409-colorize-remote-messages.sh | 8 +++++++-
|
||||
4 files changed, 24 insertions(+), 1 deletion(-)
|
||||
create mode 100644 Documentation/config/sideband.txt
|
||||
|
||||
diff --git a/Documentation/config.txt b/Documentation/config.txt
|
||||
index 0e93aef86264db..abdbfba9bd756a 100644
|
||||
--- a/Documentation/config.txt
|
||||
+++ b/Documentation/config.txt
|
||||
@@ -511,6 +511,8 @@ include::config/sequencer.txt[]
|
||||
|
||||
include::config/showbranch.txt[]
|
||||
|
||||
+include::config/sideband.txt[]
|
||||
+
|
||||
include::config/sparse.txt[]
|
||||
|
||||
include::config/splitindex.txt[]
|
||||
diff --git a/Documentation/config/sideband.txt b/Documentation/config/sideband.txt
|
||||
new file mode 100644
|
||||
index 00000000000000..3fb5045cd79581
|
||||
--- /dev/null
|
||||
+++ b/Documentation/config/sideband.txt
|
||||
@@ -0,0 +1,5 @@
|
||||
+sideband.allowControlCharacters::
|
||||
+ By default, control characters that are delivered via the sideband
|
||||
+ are masked, to prevent potentially unwanted ANSI escape sequences
|
||||
+ from being sent to the terminal. Use this config setting to override
|
||||
+ this behavior.
|
||||
diff --git a/sideband.c b/sideband.c
|
||||
index 9384cb02d56a04..8ebf1f0743e6b6 100644
|
||||
--- a/sideband.c
|
||||
+++ b/sideband.c
|
||||
@@ -20,6 +20,8 @@ static struct keyword_entry keywords[] = {
|
||||
{ "error", GIT_COLOR_BOLD_RED },
|
||||
};
|
||||
|
||||
+static int allow_control_characters;
|
||||
+
|
||||
/* Returns a color setting (GIT_COLOR_NEVER, etc). */
|
||||
static int use_sideband_colors(void)
|
||||
{
|
||||
@@ -33,6 +35,9 @@ static int use_sideband_colors(void)
|
||||
if (use_sideband_colors_cached >= 0)
|
||||
return use_sideband_colors_cached;
|
||||
|
||||
+ git_config_get_bool("sideband.allowcontrolcharacters",
|
||||
+ &allow_control_characters);
|
||||
+
|
||||
if (!git_config_get_string(key, &value)) {
|
||||
use_sideband_colors_cached = git_config_colorbool(key, value);
|
||||
} else if (!git_config_get_string("color.ui", &value)) {
|
||||
@@ -63,6 +68,11 @@ void list_config_color_sideband_slots(struct string_list *list, const char *pref
|
||||
|
||||
static void strbuf_add_sanitized(struct strbuf *dest, const char *src, int n)
|
||||
{
|
||||
+ if (allow_control_characters) {
|
||||
+ strbuf_add(dest, src, n);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
strbuf_grow(dest, n);
|
||||
for (; n && *src; src++, n--) {
|
||||
if (!iscntrl(*src) || *src == '\t' || *src == '\n')
|
||||
diff --git a/t/t5409-colorize-remote-messages.sh b/t/t5409-colorize-remote-messages.sh
|
||||
index 6a6e0d15b21050..1cd0640f200009 100755
|
||||
--- a/t/t5409-colorize-remote-messages.sh
|
||||
+++ b/t/t5409-colorize-remote-messages.sh
|
||||
@@ -105,9 +105,15 @@ test_expect_success 'disallow (color) control sequences in sideband' '
|
||||
EOF
|
||||
test_config_global uploadPack.packObjectshook ./color-me-surprised &&
|
||||
test_commit need-at-least-one-commit &&
|
||||
+
|
||||
git clone --no-local . throw-away 2>stderr &&
|
||||
test_decode_color <stderr >decoded &&
|
||||
- test_i18ngrep ! RED decoded
|
||||
+ test_i18ngrep ! RED decoded &&
|
||||
+
|
||||
+ rm -rf throw-away &&
|
||||
+ git -c sideband.allowControlCharacters clone --no-local . throw-away 2>stderr &&
|
||||
+ test_decode_color <stderr >decoded &&
|
||||
+ test_i18ngrep RED decoded
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
From c7049c2a7f47c99a67fd869f1ee89d7aa1a328d2 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Mon, 18 Nov 2024 21:42:57 +0100
|
||||
Subject: [PATCH 3/3] sideband: do allow ANSI color sequences by default
|
||||
|
||||
The preceding two commits introduced special handling of the sideband
|
||||
channel to neutralize ANSI escape sequences before sending the payload
|
||||
to the terminal, and `sideband.allowControlCharacters` to override that
|
||||
behavior.
|
||||
|
||||
However, some `pre-receive` hooks that are actively used in practice
|
||||
want to color their messages and therefore rely on the fact that Git
|
||||
passes them through to the terminal.
|
||||
|
||||
In contrast to other ANSI escape sequences, it is highly unlikely that
|
||||
coloring sequences can be essential tools in attack vectors that mislead
|
||||
Git users e.g. by hiding crucial information.
|
||||
|
||||
Therefore we can have both: Continue to allow ANSI coloring sequences to
|
||||
be passed to the terminal, and neutralize all other ANSI escape
|
||||
sequences.
|
||||
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
---
|
||||
Documentation/config/sideband.txt | 17 ++++++--
|
||||
sideband.c | 61 ++++++++++++++++++++++++++---
|
||||
t/t5409-colorize-remote-messages.sh | 16 +++++++-
|
||||
3 files changed, 84 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/Documentation/config/sideband.txt b/Documentation/config/sideband.txt
|
||||
index 3fb5045cd79581..f347fd6b33004a 100644
|
||||
--- a/Documentation/config/sideband.txt
|
||||
+++ b/Documentation/config/sideband.txt
|
||||
@@ -1,5 +1,16 @@
|
||||
sideband.allowControlCharacters::
|
||||
By default, control characters that are delivered via the sideband
|
||||
- are masked, to prevent potentially unwanted ANSI escape sequences
|
||||
- from being sent to the terminal. Use this config setting to override
|
||||
- this behavior.
|
||||
+ are masked, except ANSI color sequences. This prevents potentially
|
||||
+ unwanted ANSI escape sequences from being sent to the terminal. Use
|
||||
+ this config setting to override this behavior:
|
||||
++
|
||||
+--
|
||||
+ color::
|
||||
+ Allow ANSI color sequences, line feeds and horizontal tabs,
|
||||
+ but mask all other control characters. This is the default.
|
||||
+ false::
|
||||
+ Mask all control characters other than line feeds and
|
||||
+ horizontal tabs.
|
||||
+ true::
|
||||
+ Allow all control characters to be sent to the terminal.
|
||||
+--
|
||||
diff --git a/sideband.c b/sideband.c
|
||||
index 8ebf1f0743e6b6..afd62aa008154b 100644
|
||||
--- a/sideband.c
|
||||
+++ b/sideband.c
|
||||
@@ -20,7 +20,11 @@ static struct keyword_entry keywords[] = {
|
||||
{ "error", GIT_COLOR_BOLD_RED },
|
||||
};
|
||||
|
||||
-static int allow_control_characters;
|
||||
+static enum {
|
||||
+ ALLOW_NO_CONTROL_CHARACTERS = 0,
|
||||
+ ALLOW_ALL_CONTROL_CHARACTERS = 1,
|
||||
+ ALLOW_ANSI_COLOR_SEQUENCES = 2
|
||||
+} allow_control_characters = ALLOW_ANSI_COLOR_SEQUENCES;
|
||||
|
||||
/* Returns a color setting (GIT_COLOR_NEVER, etc). */
|
||||
static int use_sideband_colors(void)
|
||||
@@ -35,8 +39,24 @@ static int use_sideband_colors(void)
|
||||
if (use_sideband_colors_cached >= 0)
|
||||
return use_sideband_colors_cached;
|
||||
|
||||
- git_config_get_bool("sideband.allowcontrolcharacters",
|
||||
- &allow_control_characters);
|
||||
+ switch (git_config_get_maybe_bool("sideband.allowcontrolcharacters", &i)) {
|
||||
+ case 0: /* Boolean value */
|
||||
+ allow_control_characters = i ? ALLOW_ALL_CONTROL_CHARACTERS :
|
||||
+ ALLOW_NO_CONTROL_CHARACTERS;
|
||||
+ break;
|
||||
+ case -1: /* non-Boolean value */
|
||||
+ if (git_config_get_string("sideband.allowcontrolcharacters",
|
||||
+ &value))
|
||||
+ ; /* huh? `get_maybe_bool()` returned -1 */
|
||||
+ else if (!strcmp(value, "color"))
|
||||
+ allow_control_characters = ALLOW_ANSI_COLOR_SEQUENCES;
|
||||
+ else
|
||||
+ warning(_("unrecognized value for `sideband."
|
||||
+ "allowControlCharacters`: '%s'"), value);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break; /* not configured */
|
||||
+ }
|
||||
|
||||
if (!git_config_get_string(key, &value)) {
|
||||
use_sideband_colors_cached = git_config_colorbool(key, value);
|
||||
@@ -66,9 +86,37 @@ void list_config_color_sideband_slots(struct string_list *list, const char *pref
|
||||
list_config_item(list, prefix, keywords[i].keyword);
|
||||
}
|
||||
|
||||
+static int handle_ansi_color_sequence(struct strbuf *dest, const char *src, int n)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ /*
|
||||
+ * Valid ANSI color sequences are of the form
|
||||
+ *
|
||||
+ * ESC [ [<n> [; <n>]*] m
|
||||
+ */
|
||||
+
|
||||
+ if (allow_control_characters != ALLOW_ANSI_COLOR_SEQUENCES ||
|
||||
+ n < 3 || src[0] != '\x1b' || src[1] != '[')
|
||||
+ return 0;
|
||||
+
|
||||
+ for (i = 2; i < n; i++) {
|
||||
+ if (src[i] == 'm') {
|
||||
+ strbuf_add(dest, src, i + 1);
|
||||
+ return i;
|
||||
+ }
|
||||
+ if (!isdigit(src[i]) && src[i] != ';')
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void strbuf_add_sanitized(struct strbuf *dest, const char *src, int n)
|
||||
{
|
||||
- if (allow_control_characters) {
|
||||
+ int i;
|
||||
+
|
||||
+ if (allow_control_characters == ALLOW_ALL_CONTROL_CHARACTERS) {
|
||||
strbuf_add(dest, src, n);
|
||||
return;
|
||||
}
|
||||
@@ -77,7 +125,10 @@ static void strbuf_add_sanitized(struct strbuf *dest, const char *src, int n)
|
||||
for (; n && *src; src++, n--) {
|
||||
if (!iscntrl(*src) || *src == '\t' || *src == '\n')
|
||||
strbuf_addch(dest, *src);
|
||||
- else {
|
||||
+ else if ((i = handle_ansi_color_sequence(dest, src, n))) {
|
||||
+ src += i;
|
||||
+ n -= i;
|
||||
+ } else {
|
||||
strbuf_addch(dest, '^');
|
||||
strbuf_addch(dest, 0x40 + *src);
|
||||
}
|
||||
diff --git a/t/t5409-colorize-remote-messages.sh b/t/t5409-colorize-remote-messages.sh
|
||||
index 1cd0640f200009..43296ea51c5db1 100755
|
||||
--- a/t/t5409-colorize-remote-messages.sh
|
||||
+++ b/t/t5409-colorize-remote-messages.sh
|
||||
@@ -100,7 +100,7 @@ test_expect_success 'fallback to color.ui' '
|
||||
|
||||
test_expect_success 'disallow (color) control sequences in sideband' '
|
||||
write_script .git/color-me-surprised <<-\EOF &&
|
||||
- printf "error: Have you \\033[31mread\\033[m this?\\n" >&2
|
||||
+ printf "error: Have you \\033[31mread\\033[m this?\\a\\n" >&2
|
||||
exec "$@"
|
||||
EOF
|
||||
test_config_global uploadPack.packObjectshook ./color-me-surprised &&
|
||||
@@ -108,12 +108,24 @@ test_expect_success 'disallow (color) control sequences in sideband' '
|
||||
|
||||
git clone --no-local . throw-away 2>stderr &&
|
||||
test_decode_color <stderr >decoded &&
|
||||
+ test_i18ngrep RED decoded &&
|
||||
+ test_i18ngrep "\\^G" stderr &&
|
||||
+ tr -dc "\\007" <stderr >actual &&
|
||||
+ test_must_be_empty actual &&
|
||||
+
|
||||
+ rm -rf throw-away &&
|
||||
+ git -c sideband.allowControlCharacters=false \
|
||||
+ clone --no-local . throw-away 2>stderr &&
|
||||
+ test_decode_color <stderr >decoded &&
|
||||
test_i18ngrep ! RED decoded &&
|
||||
+ test_i18ngrep "\\^G" stderr &&
|
||||
|
||||
rm -rf throw-away &&
|
||||
git -c sideband.allowControlCharacters clone --no-local . throw-away 2>stderr &&
|
||||
test_decode_color <stderr >decoded &&
|
||||
- test_i18ngrep RED decoded
|
||||
+ test_i18ngrep RED decoded &&
|
||||
+ tr -dc "\\007" <stderr >actual &&
|
||||
+ test_file_not_empty actual
|
||||
'
|
||||
|
||||
test_done
|
||||
9
git.spec
9
git.spec
@ -1,7 +1,7 @@
|
||||
%global gitexecdir %{_libexecdir}/git-core
|
||||
Name: git
|
||||
Version: 2.43.0
|
||||
Release: 5
|
||||
Release: 6
|
||||
Summary: A popular and widely used Version Control System
|
||||
License: GPLv2+ or LGPLv2.1
|
||||
URL: https://git-scm.com/
|
||||
@ -23,6 +23,7 @@ Patch7: backport-CVE-2024-32465-upload-pack-disable-lazy-fetching-by-default
|
||||
Patch8: backport-CVE-2024-50349-credential_format-also-encode-host-port.patch
|
||||
Patch9: backport-CVE-2024-50349-credential-sanitize-the-user-prompt.patch
|
||||
Patch10: backport-CVE-2024-52006-credential-disallow-Carriage-Returns-in-the-protocol.patch
|
||||
Patch11: backport-CVE-2024-52005.patch
|
||||
|
||||
BuildRequires: gcc gettext
|
||||
BuildRequires: openssl-devel libcurl-devel expat-devel systemd asciidoc xmlto glib2-devel libsecret-devel pcre2-devel desktop-file-utils
|
||||
@ -307,6 +308,12 @@ make %{?_smp_mflags} test
|
||||
%{_mandir}/man7/git*.7.*
|
||||
|
||||
%changelog
|
||||
* Fri Jan 17 2025 fuanan <fuanan3@h-partners.com> - 2.43.0-6
|
||||
- Type:CVE
|
||||
- ID:CVE-2024-52005
|
||||
- SUG:NA
|
||||
- DESC:Fix CVE-2024-52005
|
||||
|
||||
* Wed Jan 15 2025 fuanan <fuanan3@h-partners.com> - 2.43.0-5
|
||||
- Type:CVE
|
||||
- ID:CVE-2024-50349 CVE-2024-52006
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user