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:
Kacper Michajłow committed 2026-01-06 13:57:21 +01:00
1 parent c63fe8ab95
commit 6c160f1aa8
1 file changed
+36
+36
View File
@@ -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) {