T09 · Insecure Skill Coding Practices
- Location
SKILL.md:610- Finding
Raw Ed25519 Private Key Disclosed Through Standard Output
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent email API integration, but it needs Review because it combines autonomous email/account authority with weak credential and installation guidance.
Review this before installing if the agent will handle real email or business data. Prefer a narrowly scoped API key in an environment variable or secrets manager, do not place credentials.json in the skill root, avoid the Ed25519 example unless private-key output is removed, pin and verify dependencies, and require explicit approval before outbound mail, webhook forwarding, attachment upload, API-key changes, or deletion requests.
SKILL.md:610Raw Ed25519 Private Key Disclosed Through Standard Output
INSTALL.md:20Mutable Remote Archive Installed Without Integrity Verification
INSTALL.md:61Unpinned Python SDK and MCP Dependencies Execute With Access to Commune Credentials
The document instructs users to create a plaintext credentials.json containing an API key. Storing live credentials on disk creates a significant exposure surface through file reads by local tools, backups, sync services, accidental commits, or insufficient filesystem isolation.
mkdir -p ~/.config/commune
cat > ~/.config/commune/credentials.json << 'EOF'
{
"api_key": "comm_your_key_here"
}
This location continues the plaintext credential-file workflow by setting permissions on ~/.config/commune/credentials.json, confirming disk-based secret storage as a supported path. Even with restrictive permissions, plaintext local credential files remain accessible to the user account, local malware, and some tooling contexts.
"api_key": "comm_your_key_here" } EOF chmod 600 ~/.config/commune/credentials.json
Or place `credentials.json` in the skill root directory.
The statement that credentials.json may be placed in the skill root directory materially increases the chance of accidental disclosure through source control, workspace sharing, packaging, or broad read access by developer tools. In context, this is more dangerous than a per-user config path because project roots are commonly synced and scanned.
chmod 600 ~/.config/commune/credentials.json
Or place `credentials.json` in the skill root directory.
## 3. Install Python SDK
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).
| Get metadata | `get_thread_metadata` | `GET /v1/threads/{id}/metadata` |
| Set status | `set_thread_status` | `PATCH /v1/threads/{id}/status` |
| Add tags | `tag_thread` | `POST /v1/threads/{id}/tags` |
| Remove tags | `untag_thread` | `DELETE /v1/threads/{id}/tags` |
| Assign | `assign_thread` | `PATCH /v1/threads/{id}/assign` |
**Status values:** `open`, `needs_reply`, `waiting`, `closed`
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# ---------------------------------------------------------------------------
def load_api_key() -> str:
"""Load API key from env var or credentials.json."""
key = os.environ.get("COMMUNE_API_KEY")
if key:
return key
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# ---------------------------------------------------------------------------
def load_api_key() -> str:
"""Load API key from env var or credentials.json."""
key = os.environ.get("COMMUNE_API_KEY")
if key:
return key
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# ---------------------------------------------------------------------------
def load_api_key() -> str:
"""Load API key from env var or credentials.json."""
key = os.environ.get("COMMUNE_API_KEY")
if key:
return key
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# ---------------------------------------------------------------------------
def load_api_key() -> str:
"""Load API key from env var or credentials.json."""
key = os.environ.get("COMMUNE_API_KEY")
if key:
return key
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# ---------------------------------------------------------------------------
def load_api_key() -> str:
"""Load API key from env var or credentials.json."""
key = os.environ.get("COMMUNE_API_KEY")
if key:
return key
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# ---------------------------------------------------------------------------
def load_api_key() -> str:
"""Load API key from env var or credentials.json."""
key = os.environ.get("COMMUNE_API_KEY")
if key:
return key
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# ---------------------------------------------------------------------------
def load_api_key() -> str:
"""Load API key from env var or credentials.json."""
key = os.environ.get("COMMUNE_API_KEY")
if key:
return key
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.
1. Go to [commune.email](https://commune.email) and sign up
2. Navigate to Settings → API Keys
3. Create a new key — it starts with `comm_`
## 2. Store Your Credentials
The guide instructs users to write API credentials to a local JSON file and explicitly allows placing that file in the skill root directory, but it does not warn about local persistence, backup/sync exposure, or accidental inclusion in version control. This can lead to credential disclosure if the working directory is shared, indexed, committed, or read by other tools.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
"api_key": "comm_your_key_here" } EOF chmod 600 ~/.config/commune/credentials.json
Or place `credentials.json` in the skill root directory.
The skill explicitly promotes autonomous email sending, receiving, inbox persistence, and webhook-driven automation, but it does not warn that these actions can expose sensitive content, contact external parties, or create durable stores of personal/business data. In an agent setting, this omission materially increases the risk of unintended disclosure, spammy outreach, and privacy noncompliance because the examples normalize automatic external communication without user-consent guardrails.
The structured extraction feature encourages automatic parsing of inbound email into JSON without warning that emails frequently contain PII, credentials, financial details, or confidential business content. That omission is risky because developers may enable broad AI extraction pipelines on all incoming mail and propagate sensitive data into downstream systems without classification, minimization, or access controls.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Step 1: Get your inbox (auto-domain, no DNS needed)
curl -s -X POST https://api.commune.email/v1/inboxes \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"local_part": "myagent", "name": "My Agent"}' | jq .
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Step 1: Get your inbox (auto-domain, no DNS needed)
curl -s -X POST https://api.commune.email/v1/inboxes \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"local_part": "myagent", "name": "My Agent"}' | jq .
The outbound email examples show how to send messages to arbitrary recipients but omit any caution that an agent may disclose internal context, secrets, or user information when composing and sending mail. In practice, this can lead to accidental data leakage or unauthorized contact because the examples make external transmission look routine and frictionless.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Save the "id" field as your INBOX_ID
# Step 2: Send your first email
curl -s -X POST https://api.commune.email/v1/messages/send \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Save the "id" field as your INBOX_ID
# Step 2: Send your first email
curl -s -X POST https://api.commune.email/v1/messages/send \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Save the "id" field as your INBOX_ID
# Step 2: Send your first email
curl -s -X POST https://api.commune.email/v1/messages/send \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Save the "id" field as your INBOX_ID
# Step 2: Send your first email
curl -s -X POST https://api.commune.email/v1/messages/send \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# Save the "id" field as your INBOX_ID
# Step 2: Send your first email
curl -s -X POST https://api.commune.email/v1/messages/send \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
curl -s -X POST https://api.commune.email/v1/domains \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"name": "mycompany.com"}' | jq .
No suspicious patterns detected.