T09 · Insecure Skill Coding Practices
- Location
scripts/ensue-api.sh:15- Finding
Unrestricted and Unsafe JSON-RPC Request Construction
- Content
View full analysis
Vulnerability Details
File Location:
scripts/ensue-api.sh, lines 15–36
Vulnerability Type: Unvalidated method selection and unsafe JSON construction
Risk Level: MediumVulnerable Code
bash METHOD="$1" ARGS="$2" if [ -z "$ENSUE_API_KEY" ]; then echo '{"error":"ENSUE_API_KEY not set. Configure in clawdbot.json under skills.entries.second-brain.apiKey or get a key at https://ensue-network.ai/dashboard"}' exit 1 fi if [ -z "$METHOD" ]; then echo '{"error":"No method specified. Available: list_keys, get_memory, create_memory, update_memory, delete_memory, discover_memories"}' exit 1 fi # Default empty args [ -z "$ARGS" ] && ARGS='{}' curl -s -X POST https://api.ensue-network.ai/ \ -H "Authorization: Bearer $ENSUE_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"$METHOD\",\"arguments\":$ARGS},\"id\":1}" \ | sed 's/^data: //'Technical Analysis
The wrapper documents six supported operations but accepts any nonempty method name without enforcing an allowlist. Consequently, a caller can request undocumented Ensue tools if the remote API exposes them to the supplied API key.
The script also constructs JSON through direct string interpolation.
METHODis inserted into a JSON string without JSON escaping, whileARGSis inserted as raw JSON without checking that it is a valid object. Values containing quotation marks or JSON structural syntax can therefore modify the intended request structure or cause malformed requests.This is not shell command injection because both expansions occur inside a quoted shell argument. The vulnerability is confined to the JSON-RPC request and the privileges granted to
ENSUE_API_KEY.Attack Path
- Attacker-controlled content influences the Agent into invoking the wrapper with a crafted method or argument value.
- The Agent executes
ensue-api.shwhile the victim’sENSUE_API_KEYis presen ...[truncated 1232 chars]
- Remediation
View remediation
Remediation Suggestions
- Enforce an explicit allowlist before making the request:
bash case "$METHOD" in list_keys|get_memory|create_memory|update_memory|delete_memory|discover_memories) ;; *) printf '%s\n' '{"error":"Unsupported method"}' >&2 exit 1 ;; esac- Validate that
ARGSis valid JSON and is an object rather than accepting arbitrary raw JSON:
bash if ! printf '%s' "$ARGS" | jq -e 'type == "object"' >/dev/null; then printf '%s\n' '{"error":"Arguments must be a valid JSON object"}' >&2 exit 1 fi- Construct the complete request with a JSON-aware serializer instead of string interpolation:
bash PAYLOAD="$( jq -n \ --arg method "$METHOD" \ --argjson arguments "$ARGS" \ '{ jsonrpc: "2.0", method: "tools/call", params: { name: $method, arguments: $arguments }, id: 1 }' )" curl --silent --show-error --fail-with-body \ -X POST 'https://api.ensue-network.ai/' \ -H "Authorization: Bearer $ENSUE_API_KEY" \ -H 'Content-Type: application/json' \ --data-binary "$PAYLOAD"-
Apply server-side authorization independently of client validation. The API should permit the token to invoke only the operations required by this Skill.
-
Preserve the documented confirmation requirement for write and delete operations, and consider requiring a second explicit confirmation before destructive deletion.
-
Return a nonzero status for transport errors and invalid API responses so malformed or rejected requests cannot be mistaken for successful operations.
