T07 · Tool Hijacking and Spoofing
- Location
handler.sh:6- Finding
Execution of Untrusted Out-of-Package Scripts and Unsafe Command Delegation
- Content
View full analysis
Vulnerability Details
File Location:
handler.sh:6-8, 17, 20, 32-34, 56-62; related delegation instructions inSKILL.md:26-29, 98-102
Vulnerability Type: Trust-boundary violation involving external local tools and unvalidated command delegation
Risk Level: HighVulnerable Code
bash WORKSPACE_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" SWITCH_SCRIPT="$WORKSPACE_DIR/scripts/switch-model.sh" STATUS_SCRIPT="$WORKSPACE_DIR/scripts/model-status.sh" LIST_SCRIPT="$WORKSPACE_DIR/scripts/list-models.sh"bash chmod +x "$SWITCH_SCRIPT" "$STATUS_SCRIPT" "$LIST_SCRIPT"bash if [ -n "$FILTER" ]; then "$LIST_SCRIPT" "$FILTER" else "$LIST_SCRIPT" fibash RESOLUTION="$($SWITCH_SCRIPT "$SELECTION")" STATUS="$(printf '%s' "$RESOLUTION" | node -e 'const fs = require("fs"); const data = JSON.parse(fs.readFileSync(0, "utf8")); process.stdout.write(data.status || "");')" case "$STATUS" in ok) COMMAND="$(printf '%s' "$RESOLUTION" | node -e 'const fs = require("fs"); const data = JSON.parse(fs.readFileSync(0, "utf8")); process.stdout.write(data.command || "");')" MODEL="$(printf '%s' "$RESOLUTION" | node -e 'const fs = require("fs"); const data = JSON.parse(fs.readFileSync(0, "utf8")); process.stdout.write(data.model || "default");')"The corresponding upper-layer instructions state:
markdown - once the script returns a unique model, execute the returned command in the current sessionmarkdown - `status: ok` - execute the returned `command`Technical Analysis
The handler derives three executable paths from a workspace directory outside the audited skill package. Those scripts are not included in the project, so their implementation and integrity cannot be established by reviewing this package. On every invocation, the handler also applies executable permissions to them and subsequently runs them with the skill's privileges.
Although shell arguments are quoted and there is no direct shell interpola ...[truncated 2696 chars]
- Remediation
View remediation
Remediation Suggestions
- Bundle
switch-model.sh,model-status.sh, andlist-models.shwithin the reviewed skill package and resolve them fromSCRIPT_DIR, rather than from a mutable workspace-level directory. - Remove runtime
chmodcalls. Set executable permissions during trusted packaging or installation and fail closed if permissions are incorrect. - If external scripts are unavoidable, verify canonical paths, file ownership, restrictive permissions, and cryptographic integrity before execution. Reject symlinks and files writable by untrusted users.
- Do not return free-form executable commands from the resolver. Return structured data such as:
json { "status": "ok", "operation": "switch_model", "provider": "openai", "model": "gpt-5.4" } - Invoke a trusted session-model API directly with the validated provider and model identifiers.
- If command-based integration is required, reconstruct the command in trusted code after strict validation. Permit only
/model defaultor/model <configured-provider/model>, where the provider and model are confirmed against the active configuration. - Reject additional arguments, control characters, newlines, command separators, unsupported operations, and malformed JSON.
- Update
SKILL.mdso the upper layer never executes a command merely because an external resolver labels its resultok. - Add tests covering replaced scripts, symlinks, writable script directories, malicious command fields, newline injection, malformed output, and unsupported model identifiers.
- Bundle
