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`. Suggested-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Mar 5, 2026 at 15:34 UTC
9ed1625a581a35d7ec2d851258cf4c7fc08c1ed7
4 files changed
+24
-1
Documentation/config.adoc
+2
@@ -523,6 +523,8 @@ include::config/sequencer.adoc[]
523
524
include::config/showbranch.adoc[]
525
526
+include::config/sideband.adoc[]
527
+
528
include::config/sparse.adoc[]
529
530
include::config/splitindex.adoc[]
Documentation/config/sideband.adoc
new
+5
@@ -0,0 +1,5 @@
1
+sideband.allowControlCharacters::
2
+ By default, control characters that are delivered via the sideband
3
+ are masked, to prevent potentially unwanted ANSI escape sequences
4
+ from being sent to the terminal. Use this config setting to override
5
+ this behavior.
sideband.c
+10
@@ -26,6 +26,8 @@ static struct keyword_entry keywords[] = {
26
{ "error", GIT_COLOR_BOLD_RED },
27
};
28
29
+static int allow_control_characters;
30
+
31
/* Returns a color setting (GIT_COLOR_NEVER, etc). */
32
static enum git_colorbool use_sideband_colors(void)
33
{
@@ -39,6 +41,9 @@ static enum git_colorbool use_sideband_colors(void)
41
if (use_sideband_colors_cached != GIT_COLOR_UNKNOWN)
42
return use_sideband_colors_cached;
43
44
+ repo_config_get_bool(the_repository, "sideband.allowcontrolcharacters",
45
+ &allow_control_characters);
46
+
47
if (!repo_config_get_string_tmp(the_repository, key, &value))
48
use_sideband_colors_cached = git_config_colorbool(key, value);
49
else if (!repo_config_get_string_tmp(the_repository, "color.ui", &value))
@@ -68,6 +73,11 @@ void list_config_color_sideband_slots(struct string_list *list, const char *pref
73
74
static void strbuf_add_sanitized(struct strbuf *dest, const char *src, int n)
75
{
76
+ if (allow_control_characters) {
77
+ strbuf_add(dest, src, n);
78
+ return;
79
+ }
80
+
81
strbuf_grow(dest, n);
82
for (; n && *src; src++, n--) {
83
if (!iscntrl(*src) || *src == '\t' || *src == '\n') {
t/t5409-colorize-remote-messages.sh
+7
-1
@@ -105,9 +105,15 @@ test_expect_success 'disallow (color) control sequences in sideband' '
105
EOF
106
test_config_global uploadPack.packObjectsHook ./color-me-surprised &&
107
test_commit need-at-least-one-commit &&
108
+
109
git clone --no-local . throw-away 2>stderr &&
110
test_decode_color <stderr >decoded &&
110
- test_grep ! RED decoded
111
+ test_grep ! RED decoded &&
112
+
113
+ rm -rf throw-away &&
114
+ git -c sideband.allowControlCharacters clone --no-local . throw-away 2>stderr &&
115
+ test_decode_color <stderr >decoded &&
116
+ test_grep RED decoded
117
'
118
119
test_done