Sanitize notifications ids as they are retransmitted over the TTY

This commit is contained in:
Kovid Goyal 2022-09-05 10:41:19 +05:30
parent c455fea729
commit f05783e64d
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 19 additions and 3 deletions

View File

@ -56,6 +56,10 @@ Detailed list of changes
- Wayland: Fix remembering window size not accurate when client side decorations are present
- Fix an issue where notification identifiers were not sanitized leading to
code execution if the user clicked on a notification popup from a malicious
source. Thanks to Carter Sande for discovering this vulnerability.
0.26.1 [2022-08-30]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,13 +1,15 @@
#!/usr/bin/env python3
# License: GPLv3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
import re
from base64 import standard_b64decode
from collections import OrderedDict
from itertools import count
from typing import Dict, Optional, Callable
from typing import Callable, Dict, Optional
from .constants import is_macos, logo_png_file
from .fast_data_types import get_boss
from .types import run_once
from .utils import log_error
NotifyImplementation = Callable[[str, str, str], None]
@ -92,6 +94,11 @@ def parse_osc_777(raw: str) -> NotificationCommand:
return ans
@run_once
def sanitize_identifier_pat() -> 're.Pattern[str]':
return re.compile(r'[^a-zA-Z0-9-_+.]+')
def parse_osc_99(raw: str) -> NotificationCommand:
cmd = NotificationCommand()
metadata, payload = raw.partition(';')[::2]
@ -107,7 +114,7 @@ def parse_osc_99(raw: str) -> NotificationCommand:
if k == 'p':
payload_type = v
elif k == 'i':
cmd.identifier = v
cmd.identifier = sanitize_identifier_pat().sub('', v)
elif k == 'e':
payload_is_encoded = v == '1'
elif k == 'd':

View File

@ -41,7 +41,7 @@ from .fast_data_types import (
update_window_title, update_window_visibility, wakeup_main_loop
)
from .keys import keyboard_mode_name, mod_mask
from .notify import NotificationCommand, handle_notification_cmd
from .notify import NotificationCommand, handle_notification_cmd, sanitize_identifier_pat
from .options.types import Options
from .rgb import to_color
from .terminfo import get_capabilities
@ -1001,6 +1001,7 @@ class Window:
self.screen.send_escape_code_to_child(OSC, f'{code};rgb:{r:04x}/{g:04x}/{b:04x}')
def report_notification_activated(self, identifier: str) -> None:
identifier = sanitize_identifier_pat().sub('', identifier)
self.screen.send_escape_code_to_child(OSC, f'99;i={identifier};')
def set_dynamic_color(self, code: int, value: Union[str, bytes]) -> None:

View File

@ -555,3 +555,7 @@ class TestDataTypes(BaseTest):
self.assertEqual(hash(SingleKey(key=1)), hash(SingleKey(key=1)))
self.assertNotEqual(hash(SingleKey(key=1, mods=2)), hash(SingleKey(key=1)))
self.assertNotEqual(SingleKey(key=1, mods=2), SingleKey(key=1))
def test_notify_identifier_sanitization(self):
from kitty.notify import sanitize_identifier_pat
self.ae(sanitize_identifier_pat().sub('', '\x1b\nabc\n[*'), 'abc')