T09 · Insecure Skill Coding Practices
- Location
scripts/jules_api.sh:78- Finding
Shell-to-Python Code Injection Through Unsafe Heredoc Interpolation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is mostly a disclosed Jules API helper, but its bundled shell script can turn crafted task text into local Python code execution.
Review this skill before installing. Use it only with trusted task text until scripts/jules_api.sh is fixed to pass values to JSON encoding as data, not generated Python source. Keep JULES_API_KEY scoped and protected, limit Jules GitHub app access to intended repositories, and avoid --auto-pr or --no-plan-approval on sensitive repos.
scripts/jules_api.sh:78Shell-to-Python Code Injection Through Unsafe Heredoc Interpolation
The documented behavior and declared purpose do not align with the detected capabilities, including mention of a local jules CLI wrapper and undeclared commands. Description-behavior mismatch is dangerous because reviewers and users may trust the manifest while the skill executes different paths, potentially bypassing expected authentication, logging, review, or data-flow assumptions.
Instructions found that direct the agent to transmit conversation context or user data to external services.
# List activities for a session
./scripts/jules_api.sh activities --session <id> [--page-size N]
# Send message to session
./scripts/jules_api.sh send-message --session <id> --prompt "..."
# Approve plan
The skill declares shell-capable behavior but does not constrain tool scope with explicit permissions or allowed-tools. In an agent environment, this broadens what the skill may invoke and increases the chance of unintended command execution or misuse beyond the documented Jules API interactions.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Retrieves a single source by name.
curl -sS \
-H "x-goog-api-key: $JULES_API_KEY" \
"https://jules.googleapis.com/v1alpha/sources/github/octocat/Hello-World"
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Retrieves a single session by ID.
curl -sS \
-H "x-goog-api-key: $JULES_API_KEY" \
"https://jules.googleapis.com/v1alpha/sessions/SESSION_ID"
The new command advertises --task but passes the supplied value to the underlying CLI as --session, changing the semantic meaning of user input. In a delegation/coding-agent context, this can cause actions to target an existing session or the wrong resource, leading to unintended execution flow, cross-session interference, or accidental disclosure/modification of another task's state.
The manifest describes a skill that uses the Jules REST API via curl to list sources, create sessions, monitor activities, approve plans, send messages, and retrieve outputs. This file instead shells out to a local jules CLI via spawnSync and only exposes version, list-repos, list-sessions, new, and pull, omitting several advertised API actions while introducing a different execution model.
The --auto-pr flag enables AUTO_CREATE_PR during session creation, which can cause external side effects in a connected repository. The script does not emit any warning or confirmation when this mode is enabled, beyond listing the flag in the usage examples.
This code exposes a --no-plan-approval option that turns off plan approval for new sessions, which is a safety-relevant behavior change. Although the flag appears in usage text, the script provides no warning, confirmation, or explicit disclosure at the point of use that approvals are being bypassed.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
case "$cmd" in
sources)
curl -sS "${BASE}/sources" "${hdr[@]}"
;;
sessions)
curl -sS "${BASE}/sessions?pageSize=${page_size}" "${hdr[@]}"
The manifest description at L003 scopes the skill to using the Jules REST API via curl, but the dependency list and later documentation introduce an additional wrapper around the Jules CLI. That is a distinct interaction mode not reflected in the stated description, even though it is presented as optional.
The manifest description lists listing sources, creating sessions, monitoring activities, approving plans, sending messages, and retrieving outputs, but does not mention deleting sessions. Documenting DELETE /sessions expands the skill's behavior beyond the declared set of operations.
Detected: suspicious.dangerous_exec