T05 · Unauthorized Access and Privilege Escalation
- Location
src/lib/mailbox.ts:64- Finding
Mailbox Path Traversal Through Unvalidated Agent Identifiers
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a coherent local agent mailbox, but it has under-scoped filesystem writes and optional automation that can trigger untrusted tasks or web callbacks.
Review this skill before installing in any shared or sensitive environment. Use only trusted agent identifiers, avoid running the heartbeat example on untrusted mail, do not enable callbacks or cloud sync without allowlists and authentication, and treat mailbox files and exports as plaintext sensitive data. Prefer archive over delete unless permanent removal is intended.
src/lib/mailbox.ts:64Mailbox Path Traversal Through Unvalidated Agent Identifiers
examples/agent-heartbeat.ts:28Unauthenticated Task Processing With Arbitrary Webhook Requests
src/lib/mailbox.ts:389Sender Spoofing and Frontmatter Injection in Message Files
src/lib/mailbox.ts:468Ambiguous Substring Matching Selects Incorrect Messages
This guide includes direct npm publish and clawhub publish commands plus promotional follow-up steps without an explicit warning that they will perform irreversible public release to external services. In an agent-skill context, users may treat documentation as operational instructions and accidentally publish unfinished, sensitive, or internal code, which can expose source, metadata, or package names publicly.
The README emphasizes local storage and manual sync options, but it does not clearly warn that messages are stored as plaintext Markdown/YAML files and that syncing the mailbox directory via Git, rsync, or backups can disclose sensitive message contents and metadata. In this skill's context, mailbox messages may contain task details, coordination data, and potentially operationally sensitive information, so understated documentation can cause users to deploy it with incorrect security assumptions.
The documentation states messages stay local by default, but it also describes automatic execution of callbacks derived from message metadata. That means untrusted message content can trigger outbound network activity, contradicting the privacy model and increasing the risk of SSRF-like behavior, data exfiltration, or unintended contact with attacker-controlled endpoints.
The heartbeat feature says it will automatically process urgent messages and execute callbacks, but it does not clearly warn users that this can cause outbound network activity and side effects without review. In an agent mailbox context, messages are inherently untrusted inputs, so auto-executing callback behavior materially increases the risk of abuse.
The cloud sync section provides commands to set a cloud URL and API key, but it does not clearly warn that messages and credentials will be transmitted to an external backend. This omission can lead users to expose private message contents and secrets to third-party infrastructure without fully understanding the security implications.
The process-urgent command performs mailbox state changes by marking urgent messages as read and archiving expired messages during processing. While it logs that urgent messages are being processed, it does not clearly disclose beforehand that invoking this command will modify message status and archive messages automatically.
The export command writes the entire mailbox, potentially including sensitive message contents and metadata, to an unencrypted JSON file in the current working directory without any warning, access control check, or safer destination handling. In multi-user or shared-agent environments, this can lead to inadvertent data exposure through permissive filesystem locations, backups, logs, or accidental commits.
The delete method irreversibly removes a message file with fs.unlinkSync, but the only disclosure is an internal log entry after deletion. There is no confirmation prompt, user-facing notice, or explicit warning comment/docstring indicating that this operation permanently deletes stored user data.
The archiveExpired method automatically rewrites message files into the archive and deletes the originals via fs.unlinkSync, affecting stored user data without any user-facing disclosure. Internal logging exists, but it does not satisfy the requirement for a visible warning or documented explanation of this safety-impacting behavior.
The security section claims no credentials are transmitted with messages, yet the documented message metadata supports arbitrary fields including callback URLs that can drive external requests. Even if credentials are not embedded in the message body itself, this design can still cause authenticated or sensitive workflow data to be sent externally, making the claim misleading and weakening operator trust.
The commands table includes a delete operation, but the markdown does not indicate whether deletion is permanent, reversible, or how it differs from archiving. For an operation that can remove user data, the skill description should include a brief warning to prevent accidental loss.
This is a manifest file, so vague-trigger review applies. The description states the skill is an 'Email system for the agent economy' that can 'Send and receive messages between agents, handlers, and users,' but it does not define when the skill should be invoked, what requests should trigger it, or any exclusions, which can contribute to overly broad matching in systems that use manifest text for routing.
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"license": "MIT",
"dependencies": {},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.0.0"
},
"repository": {
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"dependencies": {},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.0.0"
},
"repository": {
"type": "git",
The docstring for this handler says only 'read - Read a specific message', which implies a retrieval operation. In addition to displaying the message, the function changes state at L150-L153 by calling markRead on unread messages, so the inline documentation understates and contradicts the behavior's side effects.