common/msg: allow only SGR sequence in terminal output
Sanitize the remaining control codes to mitigate malicious files or scripts that could manipulate the terminal in unintended ways, such as clearing the screen or changing the terminal title. While the surface-level impact may seem minimal, control codes can be a vector for exploiting vulnerabilities in the terminal emulator itself. This can occur without user interaction, since file tags are displayed by default in mpv. Reported by: zefr0x
This commit is contained in:
1 parent
c63fe8ab95
commit
6c160f1aa8
1 file changed
+36
@@ -559,6 +559,40 @@ static void write_term_msg(struct mp_log *log, int lev, bstr text, bstr *out)
|
||||
}
|
||||
}
|
||||
|
||||
static void sanitize(bstr *text)
|
||||
{
|
||||
for (size_t i = 0; i < text->len; i++) {
|
||||
unsigned char ch = text->start[i];
|
||||
|
||||
// Allow SGR escape sequences only, filter anything else.
|
||||
if (ch == 0x1B && i + 2 < text->len && text->start[i + 1] == '[') {
|
||||
size_t j = i + 2;
|
||||
bool sgr = false;
|
||||
|
||||
while (j < text->len) {
|
||||
unsigned char c = text->start[j];
|
||||
if (c == 'm') {
|
||||
sgr = true;
|
||||
i = j;
|
||||
break;
|
||||
} else if ((c >= '0' && c <= '9') || c == ';' || c == ':') {
|
||||
j++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Nuke everything that is not an SGR sequence
|
||||
if (!sgr)
|
||||
text->start[i] = '?';
|
||||
}
|
||||
// Allow only printable > 0x20 and 0x08-0x0D (backspace, tab, newline, ...)
|
||||
else if (ch < 0x08 || (ch > 0x0D && ch < 0x20)) {
|
||||
text->start[i] = '?';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mp_msg_va(struct mp_log *log, int lev, const char *format, va_list va)
|
||||
{
|
||||
if (!mp_msg_test(log, lev))
|
||||
@@ -579,6 +613,8 @@ void mp_msg_va(struct mp_log *log, int lev, const char *format, va_list va)
|
||||
bstr_xappend(root, &root->buffer, bstr0(format));
|
||||
}
|
||||
|
||||
sanitize(&root->buffer);
|
||||
|
||||
// Remember last status message and restore it to ensure that it is
|
||||
// always displayed
|
||||
if (lev == MSGL_STATUS) {
|
||||
|
||||
Reference in new issue
Block a user