T09 · Insecure Skill Coding Practices
- Location
SKILL.md:73- Finding
Remote Request Path Overwrites the Shell Executable Search Path
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 73-90
Vulnerability Type: Request-controlled environment variable manipulation
Risk Level: MediumVulnerable Code
bash while true; do REQUEST=$(pilotctl --json recv 80 --timeout 120s) METHOD=$(echo "$REQUEST" | jq -r '.method // "GET"') PATH=$(echo "$REQUEST" | jq -r '.path // "/"') SENDER=$(echo "$REQUEST" | jq -r '.sender') case "$METHOD:$PATH" in "GET:/api/status") RESPONSE='{"status":"ok"}' ;; "GET:/api/users") RESPONSE='[{"id":1,"name":"Alice"}]' ;; *) RESPONSE='{"error":"not found"}' ;; esac pilotctl --json send-message "$SENDER" --data "$RESPONSE" doneTechnical Analysis
The script stores the remotely supplied
.pathrequest field in the special Bash variablePATH. In Bash,PATHcontrols the directories searched when resolving executable names.Assigning untrusted request data to this variable changes how all subsequent commands are resolved. The final
pilotctlcommand—and commands executed during later loop iterations—will be searched for using the attacker-provided value rather than the process's trusted executable search path.A normal API path such as
/api/statusis not a valid search path containing the required binaries. Consequently, the shell will generally fail to locatepilotctl, disrupting request processing. If an attacker can also place an executable namedpilotctlin a directory selected through the request, the script can invoke that substituted executable with the privileges of the user running the gateway.Attack Path
- The operator starts the example public daemon and listener.
- A remote client sends a request containing an attacker-selected
.pathvalue. - The statement
PATH=$(...)replaces the shell's executable search path. - The route selection completes using the modified value.
- The s ...[truncated 1181 chars]
- Remediation
View remediation
Remediation Suggestions
-
Rename the request variable so it does not collide with Bash's special
PATHvariable:bash REQUEST_PATH=$(echo "$REQUEST" | jq -r '.path // "/"') -
Use the renamed variable in route matching:
bash case "$METHOD:$REQUEST_PATH" in -
Initialize a restricted executable search path before processing requests:
bash readonly PATH='/usr/local/bin:/usr/bin:/bin' export PATH -
Resolve trusted dependencies before entering the loop and invoke them through verified absolute paths where practical:
bash PILOTCTL=$(command -v pilotctl) || exit 1 JQ=$(command -v jq) || exit 1 readonly PILOTCTL JQ -
Validate request fields before use. Restrict API paths to the expected syntax and reject values containing control characters or other malformed content.
-
Run the gateway under a dedicated, unprivileged operating-system account with minimal filesystem permissions. This limits the impact if command substitution or tool hijacking becomes possible.
-
Add explicit error handling so failures from
recv,jq, orsend-messageare logged and do not leave the gateway in an invalid state.
-
