Back to skill

Security audit

EchoDecks

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a purpose-aligned EchoDecks API client, with no hidden local persistence or unrelated behavior, though users should understand it sends account data to EchoDecks.

Install only if you trust EchoDecks with the decks, prompts, raw text, study reviews, profile/stat requests, and API key used by this skill. Keep ECHODECKS_API_KEY in a protected environment configuration, be aware that generation actions may spend credits, and avoid passing untrusted deck/card/podcast IDs until the client uses structured URL parameter encoding.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
echodecks_client.py:20
Finding

Unencoded User-Controlled Values Permit Query-Parameter Injection

Content
View full analysis

Vulnerability Details

File Location: echodecks_client.py, lines 20-30
Vulnerability Type: Query-parameter injection
Risk Level: Medium

Vulnerable Code

python
url = f"{BASE_URL}?resource={resource}"
if action:
    url += f"&action={action}"

# Merge extra params into URL if provided (e.g. deck_id for GET requests)
if params:
    for key, value in params.items():
        if value is not None:
            url += f"&{key}={value}"

Technical Analysis

The client constructs request URLs by directly concatenating parameter values into the query string. Several handlers pass user-controlled deck, card, or podcast identifiers through this code without URL encoding or format validation.

An identifier containing query delimiters such as & or = can introduce additional parameters. For example, a supplied value resembling deck123&action=status&id=target may be interpreted by the remote server as multiple parameters rather than one opaque deck identifier. The exact result depends on the EchoDecks API's handling of duplicate or conflicting query parameters.

The fixed HTTPS destination and fixed API-key header prevent this issue alone from redirecting the credential to an arbitrary host.

Attack Path

  1. An attacker supplies a crafted identifier through a command that accepts deck_id, card ID, or podcast ID.
  2. A command handler places that value in the params dictionary.
  3. make_request appends the value directly to the authenticated URL without percent-encoding it.
  4. The resulting request contains attacker-injected query delimiters and parameters.
  5. The EchoDecks API parses the injected fields under the victim's authenticated API context.
  6. If the server honors an injected or duplicate parameter, the request may operate on an unintended action or resource.

Impact Assessment

Successful exploitation may alter request semantics or target unintended EchoDecks records using the configured user's API credentia ...[truncated 268 chars]

Remediation
View remediation

Remediation Suggestions

Use the HTTP client's structured parameter support instead of manually constructing query strings. Build a parameter dictionary and pass it through the params argument:

python
def make_request(method, resource, action=None, params=None, data=None):
    headers = {
        "X-API-KEY": get_api_key(),
        "Content-Type": "application/json",
    }

    query = {"resource": resource}
    if action is not None:
        query["action"] = action
    if params:
        query.update({
            key: value
            for key, value in params.items()
            if value is not None
        })

    if method == "GET":
        response = requests.get(
            BASE_URL,
            headers=headers,
            params=query,
            timeout=30,
        )

Apply the same structured query handling to all supported HTTP methods. Additionally:

  • Validate identifiers against the documented server-side format, such as a strict UUID or alphanumeric identifier pattern.
  • Reject identifiers containing unexpected control characters.
  • Add regression tests using values containing &, =, #, spaces, and non-ASCII characters.
  • Assert that crafted values remain encoded as one parameter and cannot introduce action, resource, or id fields.
  • Enforce authorization and resource ownership independently on the EchoDecks server, because client-side validation is not an authorization boundary.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (4)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code sends request parameters and JSON payloads, along with the X-API-KEY credential, to a remote API via multiple HTTP methods. While the operations are central to the client’s purpose, there is no user-facing notice in comments, docstrings, or runtime output that deck content, study data, or authentication data will be transmitted to an external service.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · echodecks_client.py (reported line 38)May include surrounding context.

python
if method == "GET":
            response = requests.get(url, headers=headers)
        elif method == "POST":
            response = requests.post(url, headers=headers, json=data)
        elif method == "PUT":
            response = requests.put(url, headers=headers, json=data)
        elif method == "DELETE":

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · echodecks_client.py (reported line 40)May include surrounding context.

python
elif method == "POST":
            response = requests.post(url, headers=headers, json=data)
        elif method == "PUT":
            response = requests.put(url, headers=headers, json=data)
        elif method == "DELETE":
            response = requests.delete(url, headers=headers)
        else:

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The markdown states that ECHODECKS_API_KEY must be set, which implies use of a sensitive credential, but it does not include any user-facing warning about securely storing or handling that secret. Under the markdown criteria for missing user warnings, omission of privacy or system-integrity cautions around credentials can merit a finding.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.