kitty +open: Ask for permission before executing script files that are not marked as executable
This prevents accidental execution of script files via MIME type association from programs that unconditionally "open" attachments/downloaded files via MIME type associations.
This commit is contained in:
parent
79c19562b5
commit
537cabca71
@ -54,6 +54,9 @@ Detailed list of changes
|
|||||||
|
|
||||||
- Fix re-using an image id for an animated image for a still image causing a crash (:iss:`6244`)
|
- Fix re-using an image id for an animated image for a still image causing a crash (:iss:`6244`)
|
||||||
|
|
||||||
|
- kitty +open: Ask for permission before executing script files that are not marked as executable. This prevents accidental execution
|
||||||
|
of script files via MIME type association from programs that unconditionally "open" attachments/downloaded files via MIME type associations.
|
||||||
|
|
||||||
0.28.1 [2023-04-21]
|
0.28.1 [2023-04-21]
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@ -60,7 +60,7 @@ func extra_for(width, screen_width int) int {
|
|||||||
return utils.Max(0, screen_width-width)/2 + 1
|
return utils.Max(0, screen_width-width)/2 + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func choices(o *Options) (response string, err error) {
|
func GetChoices(o *Options) (response string, err error) {
|
||||||
response = ""
|
response = ""
|
||||||
lp, err := loop.New()
|
lp, err := loop.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -33,7 +33,7 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) {
|
|||||||
}
|
}
|
||||||
switch o.Type {
|
switch o.Type {
|
||||||
case "yesno", "choices":
|
case "yesno", "choices":
|
||||||
result.Response, err = choices(o)
|
result.Response, err = GetChoices(o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 1, err
|
return 1, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,6 +94,7 @@ def edit(args: List[str]) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def shebang(args: List[str]) -> None:
|
def shebang(args: List[str]) -> None:
|
||||||
|
from kitty.constants import kitten_exe
|
||||||
script_path = args[1]
|
script_path = args[1]
|
||||||
cmd = args[2:]
|
cmd = args[2:]
|
||||||
if cmd == ['__ext__']:
|
if cmd == ['__ext__']:
|
||||||
@ -111,7 +112,7 @@ def shebang(args: List[str]) -> None:
|
|||||||
cmd = line.split(' ')
|
cmd = line.split(' ')
|
||||||
else:
|
else:
|
||||||
cmd = line.split(' ', maxsplit=1)
|
cmd = line.split(' ', maxsplit=1)
|
||||||
os.execvp(cmd[0], cmd + [script_path])
|
os.execvp(kitten_exe(), ['kitten', '__confirm_and_run_shebang__'] + cmd + [script_path])
|
||||||
|
|
||||||
|
|
||||||
def run_kitten(args: List[str]) -> None:
|
def run_kitten(args: List[str]) -> None:
|
||||||
|
|||||||
48
tools/cmd/tool/confirm_and_run_shebang.go
Normal file
48
tools/cmd/tool/confirm_and_run_shebang.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
package tool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
"kitty/kittens/ask"
|
||||||
|
"kitty/tools/cli/markup"
|
||||||
|
"kitty/tools/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = fmt.Print
|
||||||
|
|
||||||
|
func ask_for_permission(script_path string) (allowed bool, err error) {
|
||||||
|
opts := &ask.Options{Type: "yesno", Default: "n"}
|
||||||
|
|
||||||
|
ctx := markup.New(true)
|
||||||
|
opts.Message = ctx.Prettify(fmt.Sprintf(
|
||||||
|
"Attempting to execute the script: :yellow:`%s`\nExecuting untrusted scripts can be dangerous. Proceed anyway?", script_path))
|
||||||
|
response, err := ask.GetChoices(opts)
|
||||||
|
return response == "y", err
|
||||||
|
}
|
||||||
|
|
||||||
|
func confirm_and_run_shebang(args []string) (rc int, err error) {
|
||||||
|
script_path := args[len(args)-1]
|
||||||
|
if unix.Access(script_path, unix.X_OK) != nil {
|
||||||
|
allowed, err := ask_for_permission(script_path)
|
||||||
|
if err != nil {
|
||||||
|
return 1, err
|
||||||
|
}
|
||||||
|
if !allowed {
|
||||||
|
return 1, fmt.Errorf("Execution permission refused by user")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exe := utils.FindExe(args[0])
|
||||||
|
if exe == "" {
|
||||||
|
return 1, fmt.Errorf("Failed to find the script interpreter: %s", args[0])
|
||||||
|
}
|
||||||
|
err = unix.Exec(exe, args, os.Environ())
|
||||||
|
if err != nil {
|
||||||
|
rc = 1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@ -67,4 +67,13 @@ func KittyToolEntryPoints(root *cli.Command) {
|
|||||||
return
|
return
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
// __confirm_and_run_shebang__
|
||||||
|
root.AddSubCommand(&cli.Command{
|
||||||
|
Name: "__confirm_and_run_shebang__",
|
||||||
|
Hidden: true,
|
||||||
|
OnlyArgsAllowed: true,
|
||||||
|
Run: func(cmd *cli.Command, args []string) (rc int, err error) {
|
||||||
|
return confirm_and_run_shebang(args)
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user