T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/githunt-search.sh:30
- Finding
- Unescaped command-line input permits JSON request-body manipulation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/githunt-search.sh:30-41` **Vulnerability Type**: Improper encoding of user-controlled data in JSON **Risk Level**: Medium ### Vulnerable Code ```bash # Build JSON payload properly payload="{\"location\": \"$location\", \"maxUsers\": 100" if [ -n "$role" ]; then payload="$payload, \"role\": \"$role\"" fi if [ -n "$skills" ]; then skills_json=$(echo "$skills" | sed 's/,/","/g' | sed 's/^/["/' | sed 's/$/"]/') payload="$payload, \"skills\": $skills_json" fi payload="$payload}" ``` ### Technical Analysis The script directly interpolates the `location`, `role`, and `skills` command-line arguments into a JSON string. It does not escape JSON metacharacters such as quotation marks, backslashes, control characters, or newlines. The `sed` transformations applied to `skills` only convert commas into apparent array delimiters. They do not perform JSON encoding and therefore do not prevent a supplied skill value from terminating the array or introducing additional JSON properties. Because the resulting payload is subsequently submitted to the configured API, crafted arguments can modify the structure and meaning of the request. Depending on how the receiving API handles duplicate or unexpected properties, an attacker may override intended search parameters, add unauthorized parameters, or cause persistent request failures. This issue does not provide local shell-command execution: the shell variables are quoted when passed to `curl`, and the payload is not evaluated as shell code. ### Attack Path 1. An attacker controls or influences arguments passed to `githunt-search.sh`. 2. The attacker places JSON syntax in the location, role, or skills argument. For example, a location value can close the original string and introduce additional properties. 3. The script concatenates the value into `payload` without JSON escaping. 4. The crafted JSON body is sent through `curl` to `${GITHUNT_API_URL}/rank ...[truncated 911 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Construct the request with a JSON-aware tool rather than string concatenation: ```bash payload=$(jq -n \ --arg location "$location" \ --arg role "$role" \ --arg skills "$skills" ' { location: $location, maxUsers: 100 } + if $role != "" then {role: $role} else {} end + if $skills != "" then {skills: ($skills | split(",") | map(select(length > 0)))} else {} end ') ``` Additional hardening should include: 1. Restrict `role` to the documented allowlist. 2. Set maximum lengths for location and skill values. 3. Reject control characters and empty skill entries. 4. Validate the generated payload with `jq -e` before transmission. 5. Enforce a documented upper bound for `maxUsers`. 6. Report API and JSON parsing failures explicitly instead of suppressing all `curl` diagnostics. ]]>
