Disallow parsing color specs as conf files for clone-in-kitty and edit-in-kitty

This commit is contained in:
Kovid Goyal 2026-04-26 10:47:24 +05:30
parent 2ead0de844
commit 5623ce52bb
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
4 changed files with 15 additions and 10 deletions

View file

@ -228,7 +228,7 @@ Detailed list of changes
- Password input in kittens: hide the cursor and display a blinking 🔒 at the end of typed characters to make it visually clear the user is entering a password
- edit-in-kitty: Ignore environment variables as some editors execute code present in env vars
- edit-in-kitty: Ignore environment variables as some editors execute code present in env vars. Similarly ignore conf file specifications for colors.
- Command palette :sc:`command_palette`: nicer grouping of aliases and combined actions (:pull:`9819`)

View file

@ -266,7 +266,7 @@ over SSH when using :doc:`kittens/ssh`.
The :command:`clone-in-kitty` command takes almost all the same arguments as the
:doc:`launch <launch>` command, so you can open a new tab instead or a new OS
window, etc. Arguments of launch that can cause code execution or that don't
window, etc. Arguments of launch that that don't
make sense when cloning are ignored. Most prominently, the following options are
ignored: :option:`--allow-remote-control <launch --allow-remote-control>`,
:option:`--copy-cmdline <launch --copy-cmdline>`, :option:`--copy-env <launch
@ -314,7 +314,8 @@ window, etc. Not all arguments are supported, see the discussion in the
In order to avoid remote code execution, kitty will only execute the configured
editor and pass the file path to edit to it and it will strip all environment
variables from the :command:`edit-in-kitty` command line.
variables from the :command:`edit-in-kitty` command line. Additionally, parsing
of colors is more limited, reading colors from config files is not allowed.
.. note:: To edit files using sudo the best method is to set the
:code:`SUDO_EDITOR` environment variable to ``kitten edit-in-kitty`` and

View file

@ -212,6 +212,7 @@ def parse_colors(
if isinstance(spec, str):
k, sep, v = spec.partition('=')
if sep == '=':
k, v = k.strip(), v.strip()
if k in allowed:
parse_conf_item(k, v, conf)
elif allow_reading_conf_files:

View file

@ -869,18 +869,24 @@ def launch(
@run_once
def clone_safe_opts() -> frozenset[str]:
return frozenset((
'window_title', 'tab_title', 'type', 'keep_focus', 'cwd', 'env', 'var', 'hold',
'window_title', 'tab_title', 'type', 'keep_focus', 'cwd', 'var', 'hold',
'location', 'os_window_class', 'os_window_name', 'os_window_title', 'os_window_state',
'logo', 'logo_position', 'logo_alpha', 'color', 'spacing', 'next_to', 'hold_after_ssh'
'logo', 'logo_position', 'logo_alpha', 'spacing', 'next_to', 'hold_after_ssh'
))
def parse_opts_for_clone(args: list[str]) -> tuple[LaunchCLIOptions, list[str]]:
def parse_opts_for_clone(args: list[str], allow_env: bool = False) -> tuple[LaunchCLIOptions, list[str]]:
unsafe, unsafe_args = parse_launch_args(args)
default_opts, default_args = parse_launch_args()
# only copy safe options, those that dont lead to local code exec
for x in clone_safe_opts():
setattr(default_opts, x, getattr(unsafe, x))
if allow_env:
# Env is not safe in general because some programs may execute code
# based on the value of env vars, such as VIMINIT for vim.
default_opts.env = unsafe.env
# color specs that dont have = will be parsed as a conf file. That is unsafe because of geninclude.
default_opts.color = [x for x in unsafe.color if '=' in x]
return default_opts, unsafe_args
@ -1074,7 +1080,7 @@ class CloneCmd:
self.bash_version = ''
self.history = ''
self.parse_message(msg)
self.opts = parse_opts_for_clone(self.args)[0]
self.opts = parse_opts_for_clone(self.args, allow_env=True)[0]
def parse_message(self, msg: str) -> None:
simple = 'pid', 'envfmt', 'shell', 'bash_version'
@ -1111,9 +1117,6 @@ def remote_edit(msg: str, window: Window) -> None:
return
cmdline = get_editor(path_to_edit=c.file_localpath, line_number=c.line_number)
c.opts.source_window = c.opts.next_to = f'id:{window.id}'
# We ignore env vars as some editors execute code present in env vars such as VIMINIT
c.opts.env = ()
c.opts.copy_env = False
w = launch(get_boss(), c.opts, cmdline)
if w is not None:
c.source_window_id = window.id