Skip to content

Commit

Permalink
sideband: mask control characters
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
dscho committed Nov 26, 2024
1 parent b01b9b8 commit 5b25741
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
17 changes: 15 additions & 2 deletions sideband.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
}


Expand Down
12 changes: 12 additions & 0 deletions t/t5409-colorize-remote-messages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

2 comments on commit 5b25741

@huyubiao
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this commit sync to https://github.com/git/git ? @dscho

@dscho
Copy link
Member Author

@dscho dscho commented on 5b25741 Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.