T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:141- Finding
Arbitrary Command Execution Through GNU sed Program Injection
- Content
View full analysis
/dev/null; then sed -i "s|^${key}=.*|${key}=${val}|" "$cfg" else echo "${key}=${val}" >> "$cfg" fi echo "Set: $key=$val" ``` ### Technical Analysis The user-controlled `key` and `val` arguments are interpolated directly into a `sed` program. Shell quoting prevents direct shell metacharacter expansion by Bash, but it does not make these values safe within the syntax of the generated `sed` expression. An attacker can include the `|` delimiter, additional `sed` commands, and GNU `sed`'s `e` flag in a configuration key. The first invocation writes the crafted key to `config.txt`. A later invocation with the same key satisfies the `grep` condition and reaches the vulnerable `sed -i` command. GNU `sed` can then interpret the injected syntax and execute the resulting pattern space through a shell. This vulnerability depends on GNU `sed` or another implementation supporting the `e` command or substitution flag. ### Attack Path 1. The attacker can influence arguments passed to `scripts/script.sh config`. 2. The attacker supplies a key containing a replacement delimiter and GNU `sed` execution syntax, for example a structure resembling: ```text x|touch /tmp/pwned #|e;# ``` 3. On the first call, the crafted key is appended to `$DATA_DIR/config.txt`. 4. The attacker invokes `config` again using the same key and a nonempty value. 5. The existing key causes execution to enter the `sed -i` update branch. 6. The crafted key changes the intended substitution expression and introduces the GNU `sed` `e` execution behavior. 7. The injected command executes with the privileges of the account running the Skill. ### Impact Assessment Successful exploitation provides arbitrary operating- ...[truncated 486 chars]- Remediation
View remediation
&2 return 1 } ``` 3. Prefer an update mechanism that treats keys and values as data rather than executable syntax. For example, use a temporary file and an `awk` variable: ```bash tmp=$(mktemp "${cfg}.XXXXXX") awk -F= -v key="$key" -v value="$val" ' BEGIN { found = 0 } $1 == key { print key "=" value found = 1 next } { print } END { if (!found) print key "=" value } ' "$cfg" > "$tmp" mv -- "$tmp" "$cfg" ``` 4. Create the configuration file with restrictive permissions and use a cleanup trap for temporary files. 5. Add regression tests containing `sed` delimiters, newlines, backslashes, semicolons, and GNU `sed` command characters. 6. If only a fixed set of settings is supported, reject every key not present in that explicit set. ]]>
