Back to skill

Security audit

Unanswered Messages

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed local reminder workflow, but it records private message details in plaintext and should be used only in a controlled workspace.

Install only if you are comfortable storing message sender details, phone numbers, chat IDs, and message previews in a local plaintext JSON file. Use restrictive file permissions, avoid logging message bodies from heartbeat jobs, and consider locking or a small database if multiple processes may update the inbox.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:46
Finding

Plaintext Storage and Disclosure of Personal Communications

Content
View full analysis
", "ts": datetime.datetime.utcnow().isoformat() + "Z", "chat_id": "", "chat_name": "", "chat_type": "direct", # or "group" "sender_name": "", "sender_phone": "", "body": "", "answered": False, "answered_at": None }) with open(INBOX, "w") as f: json.dump(data, f, indent=2) ``` The message-query functionality also prints message contents and identifiers: ```python for m in sorted(unanswered, key=lambda x: x["ts"]): ts = datetime.fromisoformat(m["ts"].replace("Z", "+00:00")).strftime("%d/%m %H:%M") print(f"📩 {m['sender_name']} | {m['chat_name']} | {ts}") print(f" > {m['body'][:100]}") print(f" Message ID: {m['id']}") ``` The heartbeat integration similarly emits message content: ```python if unanswered: # Alert Netanel or handle inline for m in unanswered: print(f"⚠️ לא ענינו ל-{m['sender_name']}: {m['body'][:80]}") ``` ### Technical Analysis The Skill instructs the agent to store sender names, telephone numbers, chat identifiers, message identifiers, and private message bodies in an unencrypted JSON file at a predictable, fixed filesystem path. It does not specify restrictive directory or file permissions, ownership verification, access-control checks, encryption, or output redaction. The query and heartbeat examples print private message excerpts. If standard output is collected by service logs, monitoring systems, terminal history, or heartbeat infrastructure, this creates an ...[truncated 1487 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:46
Finding

Non-Atomic and Unlocked Updates to the Shared Inbox File

Content
View full analysis
", "ts": datetime.datetime.utcnow().isoformat() + "Z", "chat_id": "", "chat_name": "", "chat_type": "direct", # or "group" "sender_name": "", "sender_phone": "", "body": "", "answered": False, "answered_at": None }) with open(INBOX, "w") as f: json.dump(data, f, indent=2) ``` The same unsafe read-modify-write design is used when marking a message as answered: ```python with open(INBOX) as f: data = json.load(f) for msg in data["messages"]: if msg["id"] == "": msg["answered"] = True msg["answered_at"] = datetime.datetime.utcnow().isoformat() + "Z" with open(INBOX, "w") as f: json.dump(data, f, indent=2) ``` ### Technical Analysis Each mutation reads the complete JSON document, changes an in-memory copy, and opens the destination with `"w"`. Opening with `"w"` truncates the existing file before the replacement JSON has been completely written. No exclusive lock prevents multiple logging, answer-marking, cleanup, or heartbeat-related processes from accessing the file concurrently. Consequently, two writers may read the same original state and subsequently overwrite one another. The last writer wins, silently discarding the other writer's changes. A process interruption, disk-space failure, or runtime exception after truncation can leave the inbox empty, partially written, or invalid JSON. Subsequent operations then fail at `json.load`, disrupting inbox tracking. The examples also omit sch ...[truncated 1516 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (1)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The heartbeat example prints an alert string in Hebrew only, which imposes a specific language choice in the skill's behavior. The file does not indicate that users can choose the language or that the Hebrew-only output is a documented, justified locale requirement.

Content

No source excerpt is available for this finding.