T09 · Insecure Skill Coding Practices
- Location
scripts/notify.py:13- Finding
OS Command Injection Through Notification Title and Message
- Content
View full analysis
Vulnerability Details
File Location:
scripts/notify.py, line 13
Vulnerability Type: OS command injection
Risk Level: Highpython os.system(f'notify-send -u {urgency_map.get(urgency, "normal")} "{title}" "{message}"')Technical Analysis
The
titleandmessagevalues originate from command-line arguments declared at lines 21–22 and are passed tosend_desktop_notification()at line 25. Line 13 interpolates these untrusted values directly into a command executed throughos.system().os.system()invokes a system shell. Enclosing input in double quotes does not make it safe because shell constructs such as command substitution remain active inside double-quoted strings. An attacker can use payloads containing constructs such as$(command)or escape the quoted argument and append shell commands.The broad exception handler does not prevent exploitation. Moreover,
os.system()generally returns an exit status when a command fails rather than raising an exception.Attack Path
- An attacker gains control over the notification message or title supplied to the utility, directly or through an automated task that forwards untrusted content.
argparsestores the supplied value inargs.messageorargs.title.- The value is passed without sanitization to
send_desktop_notification(). - The function inserts it into a shell command.
- The shell evaluates injected syntax before or while invoking
notify-send. - The injected command executes with the same operating-system identity and permissions as the notification process.
For example, a title or message containing shell command substitution can cause the substituted command to run even though the input is surrounded by double quotes.
Impact Assessment
Successful exploitation provides arbitrary command execution with the privileges of the user or service running the skill. Depending on those privileges and the host envi ...[truncated 310 chars]
- Remediation
View remediation
Remediation Suggestions
Remove shell interpretation and invoke
notify-sendwith a fixed executable and a separate argument list:python import subprocess def send_desktop_notification(title: str, message: str, urgency: str = "normal"): urgency_map = { "low": "low", "normal": "normal", "critical": "critical", } try: subprocess.run( [ "notify-send", "-u", urgency_map.get(urgency, "normal"), title, message, ], check=False, ) except OSError: print(f"[NOTIFICATION] {title}: {message}")Do not use
shell=True. Retain the urgency allowlist, catch only expected errors such asOSError, and consider resolvingnotify-sendto a trusted absolute path when the execution environment may have an attacker-controlledPATH. Add tests using inputs containing quotes, semicolons, dollar signs, backticks, and command-substitution syntax to verify that they are passed as literal notification text.
