T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:128- Finding
Arbitrary Command Execution Through GNU sed Program Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/script.sh, lines 128-145
Vulnerability Type: Command injection through dynamically constructedsedprogram
Risk Level: Highbash cmd_config() { local key="${1:-}" val="${2:-}" local cfg="$DATA_DIR/config.txt" if [ -z "$key" ]; then echo "=== Config ===" if [ -f "$cfg" ]; then while IFS="=" read -r k v; do echo " $k=$v"; done < "$cfg" else echo " (empty — use config <key> <value>)"; fi elif [ -z "$val" ]; then grep "^${key}=" "$cfg" 2>/dev/null | cut -d= -f2- || echo "(not set)" else if [ -f "$cfg" ] && grep -q "^${key}=" "$cfg" 2>/dev/null; then sed -i "s|^${key}=.*|${key}=${val}|" "$cfg" else echo "${key}=${val}" >> "$cfg" fi echo "Set: $key=$val" fi }Technical Analysis
The user-controlled
keyandvalarguments are interpolated directly into a GNUsedprogram. Shell double quoting only keeps the resulting text in one shell argument; it does not make that text safe assedsyntax.An attacker can include delimiter characters, regular-expression syntax, newlines, or additional
sedcommands. GNUsedprovides theecommand, which executes a command through a shell. A value containing a newline can terminate the intended substitution and insert anecommand. The unvalidatedkeycan also alter the matching expression and replacement program.Attack Path
- The attacker invokes the Skill with access to the
configcommand. - The attacker first creates a normal configuration entry:
bash scripts/script.sh config target initial - The attacker updates that existing entry with a crafted argument containing a replacement delimiter, newline, GNU
sedecommand, and comment. Conceptually, the injected value transforms the genera ...[truncated 890 chars]
- The attacker invokes the Skill with access to the
- Remediation
View remediation
Remediation Suggestions
- Do not construct a
sedprogram using untrusted input. - Restrict configuration keys to a strict allowlist such as
^[A-Za-z_][A-Za-z0-9_]*$. - Treat configuration values exclusively as data and support arbitrary values through a format with a proper serializer, such as JSON.
- If a line-oriented format must be retained, rewrite the file using a safe implementation that passes values separately from program text and explicitly handles newlines.
- Write changes to a securely created temporary file in the same directory, validate the result, set restrictive permissions, and atomically rename it over the original file.
- Add regression tests containing
seddelimiters, backslashes, ampersands, newlines, regular-expression metacharacters, and GNUsedcommands.
- Do not construct a
