T09 · Insecure Skill Coding Practices
Error
- Location
- react-component-generator.sh:2
- Finding
- Command Injection and Unrestricted File Overwrite Through Component Name## Vulnerability Details **File Location**: `react-component-generator.sh`, lines 2-14 **Vulnerability Type**: Shell command injection through dynamically constructed `sed` program and unrestricted output path **Risk Level**: High ```bash NAME="${1:-MyComponent}" TYPE="${2:-function}" cat > "$NAME.jsx" << 'JSX' export default function COMP_NAME(props) { return ( <div> <h1>COMP_NAME</h1> </div> ); } JSX sed -i "s/COMP_NAME/$NAME/g" "$NAME.jsx" ``` ### Technical Analysis The first positional argument is accepted as `NAME` without validation. Although the shell variables are quoted, quoting only prevents shell word splitting and pathname expansion. It does not make attacker-controlled data safe when that data is inserted into the source code of another interpreter. At line 14, `NAME` is embedded directly into a `sed` substitution expression: ```bash sed -i "s/COMP_NAME/$NAME/g" "$NAME.jsx" ``` Characters meaningful to `sed`, including the `/` delimiter, command separators, backslashes, newlines, and GNU `sed` flags such as `e`, can change the meaning of the generated program. Under GNU `sed`, a crafted replacement expression can reach the `e` functionality, which evaluates generated text through a shell. Successful exploitation may require constructing a matching path or directory because the same malicious value is also used as the output filename, but the script imposes no restriction preventing that setup. The same input is also used directly as a filesystem path in both the redirection and the `sed -i` target. Absolute paths, path separators, and traversal sequences such as `../` are accepted. Consequently, the script can create or truncate a writable file outside the expected working directory, provided its final path ends in `.jsx`. Existing files are overwritten without confirmation. The unused `TYPE` variable does not mitigate either issue. ### A ...[truncated 1675 chars]
- Remediation
- ## Remediation Suggestions 1. Validate the component name before using it. Restrict it to a React-compatible identifier, for example: ```bash if [[ ! "$NAME" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then printf 'Error: invalid component name\n' >&2 exit 1 fi ``` 2. Explicitly reject path separators, traversal components, control characters, and `sed` metacharacters. A strict allowlist is preferable to trying to escape every dangerous character. 3. Write generated files only beneath a designated output directory. Resolve and verify the final path before writing to ensure it remains within that directory. 4. Refuse to overwrite existing files unless the caller explicitly supplies a trusted overwrite option: ```bash output="${OUTPUT_DIR}/${NAME}.jsx" if [[ -e "$output" ]]; then printf 'Error: output file already exists\n' >&2 exit 1 fi ``` 5. Avoid constructing executable `sed` source from user input. After strict identifier validation, generate the component directly with a here-document: ```bash cat > "$output" <<JSX export default function ${NAME}(props) { return ( <div> <h1>${NAME}</h1> </div> ); } JSX ``` 6. Run the generator with least privilege, particularly in CI or build environments, and add tests covering traversal strings, delimiters, newlines, shell syntax, and attempts to overwrite existing files.
