Run notification click actions as argv, not shell strings
The click action of a notification was a free-form shell string run through `bash -lc`, safe only when every sender shell-quoted every interpolated value perfectly. One slip is RCE: a hostile yt-dlp video title forged an output record and injected an mpv option into the click command (mehmetince.net RCE, partially addressed by #7847). Add a parameterized transport: omarchy-notification-send gains --exec-arg (repeatable), encoding a JSON argv into the omarchy-exec-argv hint. The shell runs it with Quickshell.execDetached(argv) and no shell, so data an attacker controls is only ever one argument and can never be reparsed as a command. The shell fails closed on a malformed argv hint. The legacy free-form --exec string is retained but honored only from Omarchy's own omarchy-action toasts, and deprecated. Migrate all in-repo callers (screenshot, screen recording, taildrop receive, migrate-notify, crash-watch, yt-dlp host) to --exec-arg. Update docs and tests.
This commit is contained in:
@@ -24,9 +24,7 @@ readonly ignore_pattern=${OMARCHY_CRASH_IGNORE:-}
|
||||
declare -A last_notified
|
||||
|
||||
announce() {
|
||||
local comm=$1 pid=$2 exe=$3 signal=$4 exec_command
|
||||
|
||||
exec_command=$(printf 'omarchy-agent-crash %q %q %q %q' "$pid" "$comm" "$exe" "$signal")
|
||||
local comm=$1 pid=$2 exe=$3 signal=$4
|
||||
|
||||
# The shell owns org.freedesktop.Notifications, so a shell crash takes the
|
||||
# notification server down with it and a toast sent into that gap is lost.
|
||||
@@ -34,13 +32,15 @@ announce() {
|
||||
# likely to be delivered is the one most worth reporting.
|
||||
omarchy-notification-wait || return 1
|
||||
|
||||
# --exec rather than a libnotify action: the shell runs clicks from its own
|
||||
# omarchy-exec hint and never emits ActionInvoked. Keeps the default
|
||||
# --exec-arg rather than a libnotify action: the shell runs clicks from its own
|
||||
# omarchy-exec-argv hint and never emits ActionInvoked. Keeps the default
|
||||
# "omarchy-action" app name too, the only one shouldBypassDnd() lets through.
|
||||
# The argv form carries the crash details as literal arguments, so a hostile
|
||||
# process name can't be reparsed as a command when the toast is clicked.
|
||||
omarchy-notification-send \
|
||||
--urgency critical \
|
||||
--glyph "$CRASH_GLYPH" \
|
||||
--exec "$exec_command" \
|
||||
--exec-arg omarchy-agent-crash --exec-arg "$pid" --exec-arg "$comm" --exec-arg "$exe" --exec-arg "$signal" \
|
||||
"Process crashed: $comm" \
|
||||
"Click to diagnose with AI"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user