T09 · Insecure Skill Coding Practices
Warning
- Location
- screenshot-send.sh:11
- Finding
- Arbitrary Shell Execution Through Sourced Credential File<![CDATA[ ## Vulnerability Details **File Location**: `screenshot-send.sh:11-15`; related unsafe guidance in `SKILL.md:61-87` and `skill.md:61-87` **Vulnerability Type**: Executable credential configuration and excessive credential exposure **Risk Level**: Medium ### Vulnerable Code ```bash # Auto-source .env if it exists in script directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" if [ -f "$SCRIPT_DIR/.env" ]; then source "$SCRIPT_DIR/.env" fi ``` The documentation additionally recommends loading the same file into the current shell: ```bash #!/bin/bash source "$HOME/.openclaw/workspace/skills/screenshot-telegram-direct/.env" echo "✅ Environment loaded from screenshot-telegram-direct/.env" ``` It also recommends processing the file from a persistent shell profile: ```bash SKILL_DIR="$HOME/.openclaw/workspace/skills/screenshot-telegram-direct" if [ -f "$SKILL_DIR/.env" ]; then export $(grep -v '^#' "$SKILL_DIR/.env" | xargs) fi ``` ### Technical Analysis The `source` shell builtin does not treat `.env` as a passive key-value configuration file. It executes every command, substitution, redirection, function definition, and other shell construct in the file with the privileges of the invoking user. The Skill only requires three configuration values: - `TELEGRAM_BOT_TOKEN` - `TELEGRAM_CHAT_ID` - `SNAP_API_KEY` Executing arbitrary shell syntax therefore exceeds the minimum privileges necessary to obtain those values. If the Skill directory or `.env` file is modified by another user, a compromised process, an unsafe installer, or a malicious archive extraction, invoking the helper will execute the injected content. The shell-profile recommendation further increases exposure. It makes the credentials available to unrelated descendant processes and repeatedly evaluates or exports content from the Skill-controlled file. The `export $(grep ... | xargs)` construction also performs unsafe whitespace splitting and exports every configur ...[truncated 1260 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not use `source` for credential files. - Parse only the three explicitly supported keys with a strict, non-executable parser. - Reject unknown keys, duplicate keys, malformed lines, command substitutions, and shell metacharacters. - Keep credentials scoped to the helper process rather than loading them from `.bashrc` or `.zshrc`. - Require restrictive ownership and permissions, such as a user-owned file with mode `0600`. - Document that the Skill directory and credential file must not be writable by untrusted users. - Prefer a platform-provided secret store where available. For example, use a parser that treats each line strictly as data and assigns only allowlisted keys: ```bash while IFS='=' read -r key value; do case "$key" in TELEGRAM_BOT_TOKEN|TELEGRAM_CHAT_ID|SNAP_API_KEY) printf -v "$key" '%s' "$value" export "$key" ;; ''|'#'*) ;; *) printf 'Unsupported configuration key: %s\n' "$key" >&2 exit 1 ;; esac done < "$SCRIPT_DIR/.env" ``` A production implementation should also define and enforce an unambiguous escaping format rather than attempting to support arbitrary shell quoting. ]]>
