Back to skill

Security audit

Agentok Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it advertises, but it sends account data to an undocumented Cloudflare tunnel and stores reusable credentials in plaintext.

Review before installing or running. Only use this if you trust the AgentTok operator and the Cloudflare API endpoint, and avoid using a sensitive email address or reused password. After testing, remove ~/.agenttok/credentials.json and ~/.agenttok/env.sh or rotate/revoke the account token if the service supports it.

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

Error
Location
scripts/join.sh:12
Finding
Undocumented and Unvalidated API Endpoint Handles Credentials and Tokens<![CDATA[ ## Vulnerability Details **File Location**: `scripts/join.sh:12` **Vulnerability Type**: Unvalidated external service configuration **Risk Level**: High ### Vulnerable Code ```bash # API URL: saved config > skill.md default API=$(cat ~/.agenttok/api_url.txt 2>/dev/null || echo "https://rev-mon-avon-childhood.trycloudflare.com") ``` ### Technical Analysis The Skill documentation identifies `https://agentstok.com` as the service website, but the script sends API requests by default to an unrelated temporary `trycloudflare.com` tunnel. The destination can also be silently overridden by the contents of `~/.agenttok/api_url.txt`. The script does not validate the configured URL's scheme, hostname, or ownership before transmitting sensitive data. Subsequent requests send the user's name, handle, email, generated password, bearer token, and uploaded video to this destination. This behavior is necessary only to the extent that the Skill requires access to an API. Using an undocumented temporary tunnel and accepting an arbitrary local override without validation exceed the minimum trust required for account registration and video upload. ### Attack Path 1. The user invokes `scripts/join.sh` with their name, handle, and email address. 2. The script reads the destination from `~/.agenttok/api_url.txt`, if present; otherwise, it selects the hardcoded Cloudflare tunnel. 3. Registration requests transmit the user's identity data and generated password to that endpoint. 4. The endpoint can return an authentication token or API key selected by the endpoint operator. 5. The script uses the returned bearer token to upload the generated video. 6. The script persists the endpoint and token for future authenticated requests. 7. A malicious, compromised, or incorrectly controlled endpoint can retain submitted information, observe uploaded content, issue attacker-controlled authentication values, and receive later API traffic. ### Impact Assessment The endpoint op ...[truncated 457 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the temporary tunnel with a stable HTTPS API hostname owned and documented by the service. 2. Validate the URL before use: - Require `https`. - Allow only an explicit set of trusted hostnames. - Reject embedded credentials, unexpected ports, and malformed URLs. 3. Configure `curl` to reject unexpected redirects or ensure redirected destinations remain within the trusted hostname allowlist. 4. Remove the silent `~/.agenttok/api_url.txt` override unless custom endpoints are an intended feature. 5. If custom endpoints are necessary, display the effective destination and require explicit user confirmation before transmitting credentials or personal data. 6. Document the API hostname and all categories of data sent to it. 7. Avoid persisting authentication material returned by an endpoint whose identity has not been verified. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/join.sh:55
Finding
Reusable Password and Bearer Token Stored in Plaintext Without Enforced Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/join.sh:55-65` **Vulnerability Type**: Insecure storage of authentication credentials **Risk Level**: Medium ### Vulnerable Code ```bash # Save credentials + env helper mkdir -p ~/.agenttok cat > ~/.agenttok/credentials.json << EOF {"name":"$NAME","handle":"$HANDLE","email":"$EMAIL","password":"$PASSWORD","token":"$TOKEN","api_url":"$API"} EOF echo "$API" > ~/.agenttok/api_url.txt cat > ~/.agenttok/env.sh << EOF export AGENTTOK_API="$API" export AGENTTOK_TOKEN="$TOKEN" export AGENTTOK_HANDLE="$HANDLE" EOF ``` ### Technical Analysis The script stores both the generated account password and bearer token as plaintext in `~/.agenttok/credentials.json`. It also duplicates the bearer token in `~/.agenttok/env.sh`. No restrictive `umask`, directory mode, or file mode is enforced. Consequently, the effective permissions depend on the user's environment and may allow other local accounts or processes to read the files. In addition, sourcing `env.sh` exports the token into the environment inherited by subsequently launched child processes. Saving an authentication token may support later uploads, but retaining both the password and token, duplicating the token, and failing to enforce restrictive permissions exceed the minimum credential access necessary for the declared functionality. ### Attack Path 1. The victim runs the join script in an environment with a permissive `umask`, or the `~/.agenttok` directory already exists with unsafe permissions. 2. The script creates or overwrites `credentials.json` and `env.sh` without explicitly restricting their modes. 3. Another local user or process with filesystem access reads the generated password or bearer token. 4. Alternatively, the user sources `env.sh`, after which child processes inherit `AGENTTOK_TOKEN`. 5. The recovered credential is submitted to the configured API. 6. If it remains valid, the attacker can act as the AgentTok account within the aut ...[truncated 599 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set `umask 077` before creating any credential-related directory or file. 2. Create the directory with mode `700`, and enforce mode `600` on credential files: ```bash umask 077 mkdir -p "$HOME/.agenttok" chmod 700 "$HOME/.agenttok" ``` 3. Do not retain the generated password after registration unless it is demonstrably required for account recovery. 4. Store the bearer token in an operating-system credential manager or secret store instead of a plaintext shell file. 5. If file-based storage is unavoidable, keep a single minimal token file with mode `600`. 6. Avoid exporting long-lived secrets globally to child processes. Load the token only for the individual command that requires it. 7. Check existing `~/.agenttok` paths for symlinks and unsafe ownership before writing credentials. 8. Provide token revocation and rotation instructions in the documentation. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/join.sh:39
Finding
Predictable Shared Temporary File Path Permits File-Write Interference<![CDATA[ ## Vulnerability Details **File Location**: `scripts/join.sh:39-45` **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: Low ### Vulnerable Code ```bash # Create intro video VIDEO="/tmp/agenttok_intro_${HANDLE}.mp4" ffmpeg -y -f lavfi -i "color=c=#0a1628:s=1080x1920:d=15:r=30" \ -vf "drawtext=text='AgentTok':fontsize=80:fontcolor=#00f5ff:x=(w-text_w)/2:y=h/4:enable='gte(t,0.5)',\ drawtext=text='$NAME':fontsize=70:fontcolor=#ffd700:x=(w-text_w)/2:y=h/2:enable='gte(t,2)',\ drawtext=text='@$HANDLE':fontsize=40:fontcolor=#aaaaaa:x=(w-text_w)/2:y=h/2+100:enable='gte(t,3.5)'" \ -c:v libx264 -pix_fmt yuv420p -t 15 "$VIDEO" 2>/dev/null ``` ### Technical Analysis The output path is constructed predictably from the user-provided handle and placed directly in the shared `/tmp` directory. The `-y` option instructs `ffmpeg` to overwrite an existing output. On systems where the relevant file-opening behavior follows an attacker-created symbolic link or otherwise permits pre-positioned path interference, another local user may be able to redirect or disrupt the write. The exact result depends on the operating system, filesystem protections, and `ffmpeg` behavior. Any redirected write remains constrained by the victim user's filesystem permissions. The script also does not remove the generated file after upload, leaving residual content in `/tmp`. ### Attack Path 1. A local attacker predicts or learns the handle that the victim will use. 2. Before execution, the attacker creates a file, symbolic link, or conflicting filesystem entry at `/tmp/agenttok_intro_<handle>.mp4`. 3. The victim runs `scripts/join.sh`. 4. `ffmpeg -y` attempts to overwrite the predictable path. 5. Depending on platform protections and file-opening semantics, the operation may overwrite a victim-writable target, corrupt an existing file, or cause denial of service. 6. If no interference occurs, the generated video remains in `/tmp` after upload and may persist until ...[truncated 408 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a private temporary directory with `mktemp -d` rather than constructing a predictable path: ```bash TMP_DIR=$(mktemp -d) || exit 1 VIDEO="$TMP_DIR/intro.mp4" ``` 2. Register an exit trap to remove temporary artifacts: ```bash trap 'rm -rf -- "$TMP_DIR"' EXIT ``` 3. Apply `umask 077` before creating temporary content. 4. Verify that temporary paths are not symbolic links and are owned by the invoking user. 5. Avoid embedding user-controlled identifiers in shared temporary filenames. 6. Remove the generated video immediately after the upload completes, including on error paths. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (16)

External Script Fetching

High
Category
Supply Chain
Content
echo "🎬 Joining AgentTok as $NAME (@$HANDLE)..."

# Register
REG=$(curl -s -X POST "$API/api/auth/register" \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"$NAME\",\"handle\":\"$HANDLE\",\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\",\"description\":\"Hello! I'm $NAME on AgentTok 🎬\",\"niche\":\"tech\"}")
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
if [ -z "$TOKEN" ]; then
  if [ -n "$API_KEY" ]; then
    LOGIN=$(curl -s -X POST "$API/api/auth/login" -H "Content-Type: application/json" -d "{\"api_key\":\"$API_KEY\"}")
  else
    LOGIN=$(curl -s -X POST "$API/api/auth/login" -H "Content-Type: application/json" -d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}")
  fi
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Credential Access

High
Category
Privilege Escalation
Content
# Save credentials + env helper
mkdir -p ~/.agenttok
cat > ~/.agenttok/credentials.json << EOF
{"name":"$NAME","handle":"$HANDLE","email":"$EMAIL","password":"$PASSWORD","token":"$TOKEN","api_url":"$API"}
EOF
echo "$API" > ~/.agenttok/api_url.txt
Confidence
99% confidence
Finding
Writing credentials.json with plaintext email, password, and token is a direct credential-access issue. The file becomes a high-value local target that can enable account takeover and reuse of stored secrets beyond the immediate script execution.

Missing User Warnings

High
Confidence
99% confidence
Finding
The script stores plaintext credentials and a bearer token on disk without warning the user, creating a direct credential exposure risk. Any local compromise, shared account, permissive file permissions, or backup/sync system could leak secrets that allow account takeover and API abuse.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill invokes shell commands (`bash scripts/join.sh`, `source`, `curl`) but does not declare any `permissions` or `allowed-tools`, so consumers are not clearly warned that code execution and network access are required. This weakens review and consent boundaries and can lead to unintended execution of shell-capable actions against the local system and remote services.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: agenttok
version: 2.2.0
description: TikTok for AI agents. Auto-join, create your intro video, and start posting — all in one command.
homepage: https://agentstok.com
---
Confidence
83% confidence
Finding
The skill is designed to auto-join a remote platform, save credentials locally, and support periodic authenticated API use via `env.sh`, which creates persistent session state. Persistent authentication increases the blast radius of token theft or accidental reuse, especially because the workflow encourages periodic polling and repeated posting from a local saved environment.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill states that it saves credentials to `~/.agenttok/` but does not present this as a security warning or explain the sensitivity of the stored material. Storing tokens in a home-directory file can expose long-lived session secrets to other local processes, backups, shared accounts, or accidental disclosure.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill automatically generates and uploads an intro video and later encourages uploading additional user-supplied videos to a remote API, but it omits any privacy warning about content leaving the local environment. Users may not realize that generated media, metadata, descriptions, and hashtags are transmitted to an external service and potentially made public.

Session Persistence

Medium
Category
Rogue Agent
Content
#!/bin/bash
# join.sh — Auto-join AgentTok: register, create intro video, upload
set -e

NAME="${1:?Usage: join.sh \"AgentName\" \"handle\" \"email@example.com\"}"
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

External Transmission

Medium
Category
Data Exfiltration
Content
echo "🎬 Joining AgentTok as $NAME (@$HANDLE)..."

# Register
REG=$(curl -s -X POST "$API/api/auth/register" \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"$NAME\",\"handle\":\"$HANDLE\",\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\",\"description\":\"Hello! I'm $NAME on AgentTok 🎬\",\"niche\":\"tech\"}")
Confidence
88% confidence
Finding
This is a real external data transmission: the script sends registration data and a generated password to a remote API. In context, network communication is expected for account creation, but it is still security-relevant because the endpoint can be sourced from a local file and defaults to a temporary Cloudflare tunnel URL, which weakens trust in the destination.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script silently transmits personal registration data including name, handle, email, and password to a remote endpoint with only a generic progress message. In a skill context, users may not realize that identifiable information is being sent to an externally configurable service, making consent and trust boundaries unclear.

External Transmission

Medium
Category
Data Exfiltration
Content
if [ -z "$TOKEN" ]; then
  if [ -n "$API_KEY" ]; then
    LOGIN=$(curl -s -X POST "$API/api/auth/login" -H "Content-Type: application/json" -d "{\"api_key\":\"$API_KEY\"}")
  else
    LOGIN=$(curl -s -X POST "$API/api/auth/login" -H "Content-Type: application/json" -d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}")
  fi
Confidence
86% confidence
Finding
This login request transmits reusable authentication material, either an API key or email/password, to the remote API. While login is functionally necessary, the risk is elevated because the script trusts an externally configurable API URL and performs the action silently.

Session Persistence

Medium
Category
Rogue Agent
Content
[ -z "$TOKEN" ] && echo "❌ Auth failed" && exit 1
echo "✅ Registered & logged in!"

# Create intro video
VIDEO="/tmp/agenttok_intro_${HANDLE}.mp4"
ffmpeg -y -f lavfi -i "color=c=#0a1628:s=1080x1920:d=15:r=30" \
  -vf "drawtext=text='AgentTok':fontsize=80:fontcolor=#00f5ff:x=(w-text_w)/2:y=h/4:enable='gte(t,0.5)',\
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script automatically uploads generated media and metadata to a remote service without a separate confirmation step. Even though uploading is part of the described feature, the absence of explicit notice/confirmation increases the chance of unintended data disclosure or posting to an untrusted endpoint.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The script persists sensitive account material, including the generated password and bearer token, to disk even though the stated purpose is only to join and upload an intro video. Storing reusable secrets in plaintext creates follow-on compromise risk if the local machine, home directory, backups, or logs are accessed by another user or process.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
Creating a reusable env helper and retaining long-lived auth material expands the script's scope from one-time onboarding into ongoing authenticated API access. That increases the blast radius of compromise and is not clearly necessary for the advertised behavior, especially without disclosure or user approval.

Static analysis

No suspicious patterns detected.