Back to skill

Security audit

threadly

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Threadly API client, but it handles a powerful API key and some high-impact actions with under-enforced scoping and input validation.

Install only if you trust the Threadly account and API key scope, keep THREADLY_BASE_URL unset unless you control the deployment, and treat approve/reject and webhook creation as explicit user-directed actions. Review or harden the helper scripts before relying on them in automated workflows.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/common.sh:9
Finding

Bearer API credential can be transmitted to an arbitrary configured endpoint

Content
View full analysis
``` 5. The attacker records the key and uses it directly against t ...[truncated 729 chars]
Remediation
View remediation
&2; exit 1 ;; esac ``` 3. Prefer an explicit hostname allowlist, such as `api.usethreadly.co`, for normal operation. 4. If custom deployments are required, require a separate explicit opt-in and document that the destination receives the API credential. 5. Reject malformed URLs and URLs containing user-information components. 6. Keep redirect following disabled unless required. If redirects are later enabled, ensure authorization headers cannot be forwarded to a different origin. 7. Consider separating the official API mode from custom-deployment mode so accidental environment overrides fail closed. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/reject-draft.sh:9
Finding

Unescaped user input is interpolated into JSON request bodies

Content
View full analysis
}" reason="${2:?usage: reject-draft.sh }" curl -s -X POST "$BASE/public/v1/drafts/$draft_id/reject" \ -H "$AUTH_HEADER" -H "Content-Type: application/json" \ -d "{\"reason\": \"$reason\"}" | print_response ``` ```sh # scripts/webhook-subscribe.sh:10-25 target_url="${1:?usage: webhook-subscribe.sh [event_types_csv]}" event_types_csv="${2:-conversation.discovered}" # Turn "a,b,c" into a JSON array ["a","b","c"] without depending on jq being installed. event_types_json=$(printf '%s' "$event_types_csv" | awk -F, '{ out = "[" for (i = 1; i <= NF; i++) { if (i > 1) out = out "," out = out "\"" $i "\"" } print out "]" }') curl -s -X POST "$BASE/public/v1/webhook-subscriptions" \ -H "$AUTH_HEADER" -H "Content-Type: application/json" \ -d "{\"target_url\": \"$target_url\", \"event_types\": $event_types_json}" | print_response ``` ### Technical Analysis The scripts construct JSON by directly concatenating command-line values into JSON string literals. They do not escape: - Double quotation marks. - Backslashes. - Newlines and other JSON control characters. An input containing JSON metacharacters can terminate the intended string and introduce additional properties or values. Less carefully constructed input can make the body invalid and cause denial of the requested operation. This is JSON/data-format injection rather than shell command injection: the variable expansions are inside quoted shell arguments, so the reviewed code does not execute shell syntax embedded in these values. For example, a rejection reason containing a quote can alter the generated document: ```sh ./scr ...[truncated 1914 chars]
Remediation
View remediation
0))') payload=$(jq -n \ --arg target_url "$target_url" \ --argjson event_types "$event_types_json" \ '{target_url: $target_url, event_types: $event_types}') ``` Additional hardening should include: 1. Make a JSON serializer such as `jq` or Python an explicit runtime dependency. 2. Validate draft and subscription identifiers against the format required by the API before inserting them into paths. 3. Validate event types against the documented allowlist, currently `conversation.discovered`. 4. Validate the webhook URL as an HTTPS URL before submission. 5. Reject control characters and unexpected empty elements early, while still relying on proper JSON serialization for security. 6. Add regression tests using quotes, backslashes, newlines, and Unicode control characters. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 123)May include surrounding context.

text

`GET /public/v1/webhook-subscriptions` — lists this project's subscriptions (never includes
`secret`). `DELETE /public/v1/webhook-subscriptions/{id}` — revokes one.

**Before registering one:** this only works if you (or whatever is running you) have a
publicly reachable `https://` URL to receive deliveries. An ephemeral local OpenClaw session

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill invokes shell commands via curl but does not declare any explicit tool scope such as permissions or allowed-tools. That creates unnecessary ambient authority: if an agent can execute shell broadly, the skill could be used in ways beyond the documented REST interactions, and reviewers cannot easily constrain execution to the intended capability set.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

This skill is explicitly designed to send data and authorization material to an external service using curl and an API key. External transmission is expected for API-client skills, but it still carries security risk because prompts or user-provided parameters could cause unintended outbound requests, expose metadata to a third party, or misuse the bearer token against a non-default base URL.

Content

Scanner excerpt · SKILL.md (reported line 17)May include surrounding context.

md
env:
        - THREADLY_API_KEY
      bins:
        - curl
      primaryEnv: THREADLY_API_KEY
---

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/reject-draft.sh (reported line 12)May include surrounding context.

sh
draft_id="${1:?usage: reject-draft.sh <draft_id> <reason>}"
reason="${2:?usage: reject-draft.sh <draft_id> <reason>}"

curl -s -X POST "$BASE/public/v1/drafts/$draft_id/reject" \
  -H "$AUTH_HEADER" -H "Content-Type: application/json" \
  -d "{\"reason\": \"$reason\"}" | print_response

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/webhook-subscribe.sh (reported line 23)May include surrounding context.

sh
print out "]"
}')

curl -s -X POST "$BASE/public/v1/webhook-subscriptions" \
  -H "$AUTH_HEADER" -H "Content-Type: application/json" \
  -d "{\"target_url\": \"$target_url\", \"event_types\": $event_types_json}" | print_response

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script performs a network call with curl and includes an authentication header, which means it transmits credential-bearing data to a remote endpoint. In this file there is no confirmation prompt, logging, or explicit user-facing warning describing that authenticated API communication will occur.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.