T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:141- Finding
Arbitrary Command Execution Through GNU sed Configuration Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/script.sh:141-142
Vulnerability Type: Command injection through dynamically constructed GNUsedexpression
Risk Level: HighVulnerable Code
bash if [ -f "$cfg" ] && grep -q "^${key}=" "$cfg" 2>/dev/null; then sed -i "s|^${key}=.*|${key}=${val}|" "$cfg" else echo "${key}=${val}" >> "$cfg" fiTechnical Analysis
The
configcommand inserts the user-controlledkeyandvalarguments directly into a GNUsedprogram. Shell double-quoting prevents ordinary shell word splitting but does not prevent the arguments from altering the syntax interpreted bysed.A crafted value can close the replacement section with the
|delimiter and append GNUsed'seflag. When a substitution succeeds, this flag passes the replacement text to a shell for execution. The attacker can then use a semicolon and comment marker to suppress the remaining generated expression.The key is also unsafe because it is embedded unescaped in both a regular expression and the
sedexpression. This can cause expression injection, incorrect matching, or denial of service. The command-execution path specifically depends on GNUsedor another implementation supporting the substitutioneflag.Attack Path
-
Create a legitimate configuration entry so the vulnerable update branch is selected:
bash scripts/script.sh config x safe -
Update that entry with a value that terminates the replacement and enables command execution:
bash scripts/script.sh config x 'foo id|e;#' -
The script constructs an expression equivalent to:
sed s|^x=.*|x=foo id|e;#| -
GNU
sedexecutes the replacement textx=foo idthrough a shell when the matching configuration line is replaced. Theidcommand can be replaced with another command available to the invoking account. -
No elevated ...[truncated 712 chars]
-
- Remediation
View remediation
Remediation Suggestions
- Do not build a
sedprogram by interpolating user-controlled strings. - Restrict configuration keys to a conservative allowlist, such as
^[A-Za-z_][A-Za-z0-9_]*$. - Rewrite the configuration file with a parser that treats keys and values strictly as data. A structured format such as JSON, processed by a trusted JSON utility, is preferable.
- If an
awk-based implementation is used, pass data separately with-vrather than concatenating it into source code, and write to a securely created temporary file before performing an atomic replacement. - Reject control characters and embedded newlines where configuration values are intended to remain single-line.
- Set restrictive file permissions and verify that the configuration path is not a symbolic link before replacing it.
- Add regression tests containing
|,;,#, backslashes, newlines, regular-expression metacharacters, and strings designed to trigger GNUsedflags.
- Do not build a
