It is well known that a terminal tends to trust things which are printed to it through stdout/stderr, making outputting attacker-controlled data to the terminal a risky action. Is using cat -v
an effective way to sanitize untrusted data that will be output to the terminal? My threat model assumes that my terminal emulator, terminal multiplexer, or Linux VT subsystem may be vulnerable to arbitrary code execution if made to print malicious data. Attacker-controlled data can come from foreign sources, such as from a website, or from a lesser user, for example when viewing a file as root which is owned and writable by a lesser, potentially compromised user.
Some example uses:
cat -v /home/lesseruser/evil.txt
curl -I example.com | cat -v
curl -s example.com/evil.txt | cat -v
telnet 198.51.100.98 23 | cat -v
From section 3.1 of the coreutils GNU Info page:
-v
--show-nonprinting
Display control characters except for LFD and TAB using ^ notation
and precede characters that have the high bit set with M-.
From the source code for src/cat.c
, in coreutils version 8.28:
if (show_nonprinting)
{
while (true)
{
if (ch >= 32)
{
if (ch < 127)
*bpout++ = ch;
else if (ch == 127)
{
*bpout++ = '^';
*bpout++ = '?';
}
else
{
*bpout++ = 'M';
*bpout++ = '-';
if (ch >= 128 + 32)
{
if (ch < 128 + 127)
*bpout++ = ch - 128;
else
{
*bpout++ = '^';
*bpout++ = '?';
}
}
else
{
*bpout++ = '^';
*bpout++ = ch - 128 + 64;
}
}
}
else if (ch == '\t' && !show_tabs)
*bpout++ = '\t';
else if (ch == '\n')
{
newlines = -1;
break;
}
else
{
*bpout++ = '^';
*bpout++ = ch + 64;
}
ch = *bpin++;
}
}
Is using cat -v
to sanitize untrusted input before printing useful for my threat model?