T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/whatsapp_happybday.py:115
- Finding
- Shell Command Injection Through Dynamically Constructed wacli Commands<![CDATA[ ## Vulnerability Details **File Location**: `scripts/whatsapp_happybday.py`, lines 115-119, 134-135, and 218-219 **Vulnerability Type**: OS command injection through `shell=True` **Risk Level**: High ### Vulnerable Code ```python def run_wacli_command(cmd): """Execute wacli command""" try: result = subprocess.run( cmd, shell=True, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=60 ) return result.stdout, result.stderr, result.returncode except Exception as e: return "", str(e), 1 ``` ```python def get_recent_messages(group_jid, today): """Get recent messages from a group (Text fields only)""" cmd = f'wacli messages list --chat "{group_jid}" --after {today} --json' stdout, stderr, rc = run_wacli_command(cmd) ``` ```python def send_message(group_jid, msg): cmd = f'wacli send text --message "{msg}" --to "{group_jid}"' stdout, stderr, rc = run_wacli_command(cmd) if rc != 0 or not stdout.strip(): return False return True ``` ### Technical Analysis The program interpolates `group_jid` and `msg` into command strings and executes those strings through a command shell. Quoting the interpolated values with double quotes does not make this safe: embedded quotation marks, command substitutions, and other shell metacharacters can terminate or alter the intended argument. The generated message can include content from the locally customizable `messages.json` file, while group identifiers originate from `wacli` output. If either source contains shell syntax, the shell may interpret it as a separate command rather than as literal WhatsApp message data. The application does not need shell parsing for its declared functionality. `wacli` can be invoked directly with an argument array, so use of `shell=True` exceeds the minimum execution capability required. ### Attack Path ...[truncated 1376 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove `shell=True` and pass each command as an argument list: ```python def run_wacli_command(args): return subprocess.run( args, shell=False, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=60, check=False, ) run_wacli_command([ "wacli", "messages", "list", "--chat", group_jid, "--after", today, "--json", ]) run_wacli_command([ "wacli", "send", "text", "--message", msg, "--to", group_jid, ]) ``` - Validate group JIDs against the exact WhatsApp JID syntax expected by `wacli`. - Validate custom dictionary files against a strict JSON schema. - Run the Skill under a dedicated, minimally privileged account. - Add tests containing quotation marks, command substitutions, semicolons, and newline characters to confirm they are treated as literal argument content. ]]>
