T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/scan.sh:37
- Finding
- Command Injection Through an Unquoted Repository Path in CodeQL Build Commands<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scan.sh`, lines 37-65 **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```bash build_cmd="" case "$LANG" in java) if [[ -f "$REPO/pom.xml" ]]; then build_cmd="mvn clean install -DskipTests -f $REPO/pom.xml" elif [[ -f "$REPO/build.gradle" ]]; then build_cmd="gradle build -x test -p $REPO" fi ;; cpp) [[ -f "$REPO/Makefile" ]] && build_cmd="make -C $REPO" ;; javascript|python) build_cmd="" # 无需构建 ;; esac # ── 3. 创建 CodeQL 数据库 ──────────────────────────────────────── echo "⏳ 创建 CodeQL 数据库 (语言: $LANG)..." codeql_args=(database create "$DB_PATH" --language="$LANG" --source-root="$REPO" --overwrite ) [[ -n "$build_cmd" ]] && codeql_args+=(--command="$build_cmd") ``` ### Technical Analysis The repository path is accepted from the first command-line argument and interpolated directly into a build-command string. The Maven, Gradle, and Make variants all embed `$REPO` without shell-safe quoting. Using a Bash array protects the initial invocation of the `codeql` executable, but it does not make the contents of `--command` safe. CodeQL must subsequently execute that value as a build command. At that stage, the command string can be interpreted by a shell, causing shell syntax embedded in the repository path to be evaluated. An attacker who controls the scanned repository's path can use a valid directory name containing command substitution or other shell syntax. If the directory also contains the corresponding build marker, such as `pom.xml`, `build.gradle`, or `Makefile`, the unsafe command path is selected. There is also an inherent secondary risk: Maven plugins, Gradle tasks, and Make recipes from the scanned repository execute during database creation. A hostile repository can therefore execute code even when its path is benign. The Skill does not warn about this trust boundary or provide isolation. ## ...[truncated 1639 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not construct shell command strings by concatenating user-controlled paths. 2. Resolve the repository path to a canonical absolute path and reject paths containing control characters. 3. Use a fixed wrapper script and pass the repository path as a positional argument rather than embedding it into `--command`. 4. If CodeQL requires a single command string, apply robust shell quoting using a mechanism such as `printf '%q'` for every dynamic argument. Do not implement ad hoc escaping. 5. Verify that the canonical repository path points to an expected directory and is not a symbolic-link escape from an approved workspace. 6. Run all target builds in a disposable sandbox or container with: - An unprivileged user. - No host credentials or sensitive environment variables. - Restricted or disabled networking. - Minimal filesystem mounts. - Resource and execution-time limits. - A disposable writable workspace. 7. Treat Maven, Gradle, and Make build logic as untrusted executable code. Clearly disclose this behavior before scanning a repository. 8. Consider requiring explicit user confirmation before executing repository-controlled build steps. ]]>
