Back to skill

Security audit

Index Cards

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent physical greeting-card service, but users should understand that mailing details go to the provider and optional saved contacts are kept locally in plaintext.

Install only if you are comfortable sending recipient name, mailing address, phone number, artwork, occasion, and message text to Index Cards when you approve an order. Avoid opting into the local contacts cache unless you want those details saved on disk, and review the full address, message, cost, and recipient before confirming any order.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:135
Finding
Plaintext Storage of Sensitive Contact and Delivery Data<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 135-147 **Vulnerability Type**: Plaintext storage of sensitive personal data **Risk Level**: Medium ### Vulnerable Code ```markdown ## Local contacts database (opt-in) If the user agrees to saving contacts, maintain `~/indexcards/birthdays.json` as a local cache. ```json {"contacts": [{"name": "Kiall Wheatley", "birthday": "02-19", "relationship": "friend", "address": {"address1": "123 Main St", "city": "Springfield", "state": "IL", "zip": "62704", "country": "US"}, "phone": "+15551234567", "notes": "Loves hiking. Prefers watercolor.", "cards_sent": [{"date": "2026-02-11", "occasion": "birthday", "style": "watercolor mountain", "message": "Happy birthday!", "order_id": "e5f67c35"}]}]} ``` Rules: MM-DD birthday format (no year). Don't duplicate — match on name. Update with every new piece of info. Append to `cards_sent` after every order. Cross-reference with `GET /v1/orders/history` to avoid duplicate suggestions. ``` ### Technical Analysis The Skill instructs the agent to persist sensitive personal information in a predictable plaintext JSON file at `~/indexcards/birthdays.json`. The stored fields may include names, birthdays, relationships, full postal addresses, telephone numbers, personal notes, card messages, and order history. User consent controls whether the file is created, but it does not mitigate the security risks arising after creation. The instructions do not require owner-only file permissions, encryption at rest, secure atomic writes, ownership checks, integrity validation, data minimization, or a retention period. Consequently, the effective protection of the file depends on the runtime's default umask, home-directory permissions, backup configuration, and access available to other local processes. Because the same file is later used to prefill delivery information, unauthorized modification presents an integrity risk in addition to confidentiality exposure. ...[truncated 1796 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store contact records in an operating-system-provided encrypted credential or application-data facility rather than a plaintext JSON file. 2. If file-based storage is unavoidable: - Create the parent directory with mode `0700`. - Create the data file with mode `0600`. - Set permissions explicitly instead of relying on the process umask. - Reject symbolic links and verify the file owner, type, and permissions before every read or write. - Use atomic writes through a securely created temporary file in the same protected directory. 3. Encrypt sensitive fields at rest using a key held by the operating-system keychain or secret store. Do not store the encryption key beside the data. 4. Minimize retained data. Store only fields the user separately authorizes and avoid retaining card messages, personal notes, telephone numbers, or full addresses when they are no longer required. 5. Provide explicit commands to inspect, update, export, and permanently delete stored records. 6. Define a retention period and automatically remove stale delivery information unless the user renews consent. 7. Treat cached addresses as untrusted input. Display the complete address clearly and require explicit confirmation immediately before every irreversible order. 8. Record or verify a trusted contact identifier rather than matching records only by name, which can collide or be manipulated. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (3)

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The skill’s privacy statement is materially inconsistent with its documented behavior. It says contact data is not sent to the API, but the order flow explicitly sends recipient name, mailing address, and phone number to `/v1/orders`; this can mislead users and downstream systems about data disclosure, undermining informed consent for sensitive physical-address data.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The description says to use the skill when the user 'mentions a birthday or occasion,' which is broad enough to overlap with ordinary conversation that is not actually a request to send a card. The trigger scope is not bounded by explicit activation phrases or exclusion conditions, so the skill may be invoked unintentionally.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
### What this skill does NOT do

- Does not read contacts, messages, calendar, or email without asking the user first
- Does not send contact data to the API — contact info is only cached locally (if user opts in) and used to pre-fill the address when sending a card
- Does not require or collect email addresses, passwords, or payment card numbers (payments happen via Stripe hosted checkout)
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Static analysis

No suspicious patterns detected.