Back to skill

Security audit

Kindroid Interact

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with Kindroid API use, but it needs review because it stores a persistent API key and the shell wrapper has unsafe temporary-file handling that can corrupt user-writable files on shared systems.

Install only if you are comfortable giving the skill a persistent Kindroid API key and letting it send authenticated messages and chat-break requests to Kindroid. Prefer using a dedicated/revocable key, restrict access to ~/.config/kindroid, avoid using the shell wrapper on shared multi-user systems until the /tmp rate-limit file and JSON escaping issues are fixed, and do not rely on the advertised webhook feature without separate review.

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
kindroid.sh:8
Finding

Predictable Temporary File Permits Symlink-Based File Overwrite

Content
View full analysis
"$RATE_LIMIT_FILE" } ``` ### Technical Analysis The rate-limit state is stored at a fixed, globally predictable path in the shared `/tmp` directory. The script does not securely create the file, reject symbolic links, verify ownership, or confirm that the existing object is a regular file controlled by the current user. Shell redirection follows symbolic links. Consequently, another local user can create `/tmp/kindroid_last_call` as a symbolic link to any file that the victim running the Skill is permitted to overwrite. When the Skill executes `date +%s > "$RATE_LIMIT_FILE"`, the linked target is truncated and replaced with a timestamp. The script also reads existing file content and uses it in Bash arithmetic without first verifying that it contains only a valid integer. Attacker-controlled content can therefore trigger arithmetic parsing errors or unexpected expression handling, providing an additional denial-of-service vector. The shared file is also not protected by locking, so concurrent executions can race with one another. ### Attack Path 1. A local attacker determines that the victim uses the Kindroid Skill. 2. Before the victim runs the CLI, the attacker creates a symbolic link at the predictable path: ```bash ln -s /path/to/victim-writable-file /tmp/kindroid_last_call ``` 3. The victim invokes `kindroid.sh send`, `break`, or `status`. 4. `api_call` invokes `check_rate_limit`. 5. The final redirection follows the ...[truncated 933 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
kindroid.sh:131
Finding

Unescaped Input Allows JSON Request-Payload Injection

Content
View full analysis
/dev/null info "Chat break successful" } cmd_status() { local companion="${1:-default}" get_credentials "$companion" info "Checking status for ${companion}..." api_call "status" "{\"ai_id\": \"$AI_ID\"}" } ``` ### Technical Analysis The script constructs JSON by directly interpolating user-controlled message or greeting text and configuration-derived AI identifiers into quoted strings. It does not apply JSON escaping. Input containing a quotation mark, backslash, newline, or JSON syntax can terminate the intended string value and alter the remainder of the request object. At minimum, ordinary messages containing these characters can produce invalid JSON and cause failed requests. Cr ...[truncated 1527 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
SKILL.md:38
Finding

Credential File Is Created Before Restrictive Permissions Are Applied

Content
View full analysis
~/.config/kindroid/credentials.json << EOF { "default_ai": "your_primary_ai_id", "api_key": "your_kn_api_key", "companions": { "nickname1": "ai_id_1", "nickname2": "ai_id_2" } } EOF chmod 600 ~/.config/kindroid/credentials.json ``` ### Technical Analysis The setup instructions write the plaintext API key to `credentials.json` before applying mode `0600`. Initial permissions are determined by the user's current umask. With a common umask of `022`, a newly created file may initially have mode `0644`, making it readable by other local users until the subsequent `chmod` completes. The final `0600` mode is appropriate. Reading a Kindroid API key from a dedicated credential file is also necessary for the declared authenticated API functionality and does not, by itself, exceed minimum privilege. The issue is the non-atomic creation procedure and the lack of an explicitly private mode for the containing directory. ### Attack Path 1. A user follows the documented setup instructions on a multi-user system with a permissive umask. 2. Shell redirection creates `credentials.json` with permissions derived from that umask. 3. The API key is written while the file may be readable by other local users. 4. Before `chmod 600` completes, another local process opens and reads the file. 5. The attacker obtains the Kindroid API key and associated AI identifiers. The exposure window is brief, so exploitation generally requires local access and active monitoring of the documented path. ### Impact Assessment Disclosure of the API key may permit an attacker to authenticate to the Kindroid API with the victim's authority. Depending on the permissions and behavior of that API key, the attacker may be able to send messages, initiate cha ...[truncated 262 chars]
Remediation
View remediation
"$HOME/.config/kindroid/credentials.json" <<'EOF' { "default_ai": "your_primary_ai_id", "api_key": "your_kn_api_key", "companions": { "nickname1": "ai_id_1", "nickname2": "ai_id_2" } } EOF chmod 700 "$HOME/.config/kindroid" chmod 600 "$HOME/.config/kindroid/credentials.json" ``` For stronger guarantees, create the file with its final permissions before writing: ```bash mkdir -p "$HOME/.config/kindroid" chmod 700 "$HOME/.config/kindroid" install -m 600 /dev/null "$HOME/.config/kindroid/credentials.json" ``` Then write the JSON content to the pre-created file. The implementation should also verify that the credential path is a regular file owned by the current user before reading it. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented purpose understates behaviors involving local credential access, file permission changes, temporary state writes, and webhook-related functionality. When a skill's declared purpose does not fully match its operational behavior, users and agent frameworks may grant trust or permissions without understanding the real data access and side effects.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

The skill is explicitly designed to store and access an API key from a local credentials file, which means it handles sensitive secrets. In agent environments, local credential access is inherently dangerous because any overbroad shell/file capability, logging, or downstream tool misuse could expose the key and enable unauthorized API use.

Content

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

md
## Security First 🔒

Your Kindroid API key (`kn_...`) is sensitive. This skill includes safeguards:
- Credentials are stored in `~/.config/kindroid/credentials.json`
- File permissions are automatically set to `600` (owner read/write only)
- All API calls use HTTPS and proper authentication headers
- Rate limiting to prevent API abuse

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The setup instructions tell users to create a plaintext credentials.json file containing a live API key. While common, this creates a high-value local secret target that may be readable by misconfigured tools, backups, shell history, or other skills if permissions are not tightly constrained.

Content

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

  1. Create your credentials file:
bash
mkdir -p ~/.config/kindroid
cat > ~/.config/kindroid/credentials.json << EOF
{
  "default_ai": "your_primary_ai_id",
  "api_key": "your_kn_api_key",

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The reference to the credentials file near the permission-setting step reinforces that the skill relies on persistent local secret storage. Persistent plaintext credentials increase the blast radius of host compromise or over-permissioned agent tooling because the key remains available beyond a single session.

Content

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

} } EOF chmod 600 ~/.config/kindroid/credentials.json

text

## Basic Usage

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
# Constants
VERSION="1.0.0"
CONFIG_DIR="$HOME/.config/kindroid"
CONFIG_FILE="$CONFIG_DIR/credentials.json"
RATE_LIMIT_FILE="/tmp/kindroid_last_call"
MIN_DELAY=3  # seconds between API calls
DEFAULT_TIMEOUT=300  # 5 minutes default timeout

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · kindroid.js (reported line 22)May include surrounding context.

js
# Constants
VERSION="1.0.0"
CONFIG_DIR="$HOME/.config/kindroid"
CONFIG_FILE="$CONFIG_DIR/credentials.json"
RATE_LIMIT_FILE="/tmp/kindroid_last_call"
MIN_DELAY=3  # seconds between API calls
DEFAULT_TIMEOUT=300  # 5 minutes default timeout

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · kindroid.sh (reported line 8)May include surrounding context.

sh
# Constants
VERSION="1.0.0"
CONFIG_DIR="$HOME/.config/kindroid"
CONFIG_FILE="$CONFIG_DIR/credentials.json"
RATE_LIMIT_FILE="/tmp/kindroid_last_call"
MIN_DELAY=3  # seconds between API calls
DEFAULT_TIMEOUT=300  # 5 minutes default timeout

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documentation describes use of shell commands and environment-sensitive operations, but it declares no explicit tool scope such as allowed shell access or file/env permissions. This weakens the trust boundary for agents because consumers cannot clearly see that the skill needs command execution and local file access, increasing the chance of overbroad or unexpected execution.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
79% confidence
Finding

The skill instructs users to keep the API key in a persistent local file under the home directory, which creates long-lived session/authentication material on disk. Persistent tokens are more exposed to theft from other local processes, backups, or later compromise than ephemeral credentials.

Content

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

md
Your Kindroid API key (`kn_...`) is sensitive. This skill includes safeguards:
- Credentials are stored in `~/.config/kindroid/credentials.json`
- File permissions are automatically set to `600` (owner read/write only)
- All API calls use HTTPS and proper authentication headers
- Rate limiting to prevent API abuse

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 · SKILL.md (reported line 50)May include surrounding context.

} } EOF chmod 600 ~/.config/kindroid/credentials.json

text

## Basic Usage

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The documentation advertises webhook support even though the stated scope centers on direct Kindroid API messaging and chat management. Expanding into callback delivery changes the data-flow model by sending conversation-related data to external endpoints, which is a materially different and more privacy-sensitive capability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The webhook example encourages sending callbacks to an arbitrary external URL without warning that chat contents, metadata, or identifiers may be transmitted off-platform. This can lead to inadvertent data disclosure, especially when users assume the skill only talks to the official Kindroid API.

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 · kindroid.sh (reported line 84)May include surrounding context.

sh
\"api_key\": \"your_kn_key\",
  \"companions\": {}
}' > $CONFIG_FILE
chmod 600 $CONFIG_FILE"
    fi

    if [[ $(stat -c %a "$CONFIG_FILE") != "600" ]]; then

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 · kindroid.sh (reported line 89)May include surrounding context.

sh
\"api_key\": \"your_kn_key\",
  \"companions\": {}
}' > $CONFIG_FILE
chmod 600 $CONFIG_FILE"
    fi

    if [[ $(stat -c %a "$CONFIG_FILE") != "600" ]]; then

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 · kindroid.sh (reported line 119)May include surrounding context.

sh
check_rate_limit

    local response
    response=$(curl -s -X POST \
        "https://api.kindroid.ai/v1/$endpoint" \
        -H "Authorization: Bearer $API_KEY" \
        -H "Content-Type: application/json" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · kindroid.sh (reported line 120)May include surrounding context.

sh
local response
    response=$(curl -s -X POST \
        "https://api.kindroid.ai/v1/$endpoint" \
        -H "Authorization: Bearer $API_KEY" \
        -H "Content-Type: application/json" \
        -d "$data" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The break command invokes the chat-break endpoint to start a new conversation, which is an irreversible state-changing operation, but the function only prints a success message after execution. There is no confirmation prompt or explicit warning in this code path that the existing conversation context will be discarded before performing the action.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The "Security First" section presents rate limiting as an included safeguard, which reads like an implemented guarantee. In this file, however, there is only descriptive documentation and no code implementing or enforcing rate limiting, so the claim overstates what this file actually does.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest describes interacting with Kindroid companions via the official API, including messaging and chat management. While network API use is expected, the code also directly accesses a local credentials file under ~/.config/kindroid/credentials.json, which is an additional local-file access capability not mentioned in the stated purpose.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.