T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:143- Finding
GNU sed Program Injection Through Unescaped Configuration Values
- Content
View full analysis
/dev/null; then sed -i "s|^${key}=.*|${key}=${val}|" "$cfg" else echo "${key}=${val}" >> "$cfg" fi ``` ### Technical Analysis The configuration key and value are inserted directly into a `sed` program without escaping. Shell quoting prevents ordinary shell expansion of these variables, but it does not make them safe when interpreted as `sed` syntax. An attacker-controlled value can contain the `|` delimiter and newline characters, terminate the intended substitution, and append another GNU `sed` command. GNU `sed` supports the `e` command, which executes an operating-system command. A malicious value can therefore transform the generated program into a substitution followed by an attacker-selected command. For example, after a configuration entry named `x` exists, a value conceptually equivalent to the following can inject an execution command: ```text safe| e id > /tmp/motor-command-output # ``` The resulting `sed` program contains an independent `e` instruction. The configuration key is also used as an unescaped regular expression, creating additional regex and delimiter injection opportunities. ### Attack Path 1. The attacker first ensures that the targeted key exists in `$DATA_DIR/config.txt`, for example by invoking: ```bash scripts/script.sh config x initial ``` 2. Because the key now exists, a subsequent invocation reaches the vulnerable `sed -i` branch. 3. The attacker supplies a value containing a delimiter, newline, GNU `sed` `e` command, and comment syntax. 4. The value terminates the intended substitution and introduces a separate executable `sed` instruction. 5. GNU `sed` executes the injected command with the privileges of the user running the Sk ...[truncated 781 chars]- Remediation
View remediation
&2 return 1 fi ``` 2. Reject newline, carriage-return, NUL, and other control characters in values unless multiline values are an explicit requirement. 3. Replace the dynamic `sed` expression with an implementation that passes values as data rather than program text. For example, create a temporary file safely and use `awk` variables: ```bash tmp=$(mktemp "${cfg}.tmp.XXXXXX") || return 1 trap 'rm -f "$tmp"' RETURN awk -F= -v key="$key" -v value="$val" ' BEGIN { updated = 0 } $1 == key { print key "=" value updated = 1 next } { print } END { if (!updated) print key "=" value } ' "$cfg" > "$tmp" && chmod --reference="$cfg" "$tmp" 2>/dev/null || true mv -- "$tmp" "$cfg" ``` 4. Ensure temporary files are created in the same directory as the destination and are atomically renamed into place. 5. Add regression tests containing `|`, backslashes, regular-expression metacharacters, command-like strings, and embedded newlines. ]]>
