T09 · Insecure Skill Coding Practices
- Location
src/index.ts:633- Finding
Paid and Irreversible Order Submission Lacks Enforced User Confirmation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a coherent Handwrytten API wrapper, but it can submit paid physical-mail orders and mutate account data without enforced confirmation safeguards.
Review this before installing. Use it only with an API key/account where the assistant is allowed to spend credits, send physical mail, process recipient addresses, and change saved Handwrytten assets. Require human review in your client before live sends, bulk sends, gift-card orders, basket submission, and deletions; consider using a limited or test account where possible.
src/index.ts:633Paid and Irreversible Order Submission Lacks Enforced User Confirmation
The public description frames the skill narrowly as sending handwritten notes, but the documented capabilities also include recipient and sender address-book management, order history, QR code lifecycle actions, custom image upload, custom card creation, and geographic prospecting. This mismatch can mislead users and reviewers about the true data access and action surface, increasing the chance of unintended PII handling, broader account modification, or costly side effects.
The public description frames the skill narrowly as sending handwritten notes, but the documented capabilities also include recipient and sender address-book management, order history, QR code lifecycle actions, custom image upload, custom card creation, and geographic prospecting. This mismatch can mislead users and reviewers about the true data access and action surface, increasing the chance of unintended PII handling, broader account modification, or costly side effects.
The README promotes tools that can trigger real-world actions with cost and privacy consequences—sending physical mail, handling recipient addresses, and supporting bulk sends—without any user-facing warnings, confirmation guidance, or notice about charges and sensitive personal data handling. In an MCP context, this is dangerous because an AI assistant may operationalize these actions quickly at scale, increasing the risk of accidental mailing, exposure of PII, or unintended spend.
The skill declares access to an environment secret (HANDWRYTTEN_API_KEY) and requires node, but it does not declare any explicit tool scope such as allowed tools or permissions. That weakens least-privilege guarantees and makes it harder for a host or reviewer to constrain what the skill may invoke or access at runtime.
This package advertises sending handwritten notes through an API, which necessarily involves transmitting user-provided message content and recipient details to an external service. Failing to disclose that data leaves the local environment can mislead users and agents, increasing the chance of unintended disclosure of personal or sensitive information.
The skill description frames the capability as simply sending handwritten notes, but the implementation exposes a much broader administrative surface including account inspection, address-book management, QR code creation/deletion, custom-card design, gift card handling, basket submission, and prospecting. This scope mismatch is dangerous because an AI agent or user may grant trust based on the narrow description while the server can perform materially different and more sensitive actions, increasing the chance of unintended data access or destructive operations.
The delete_qr_code tool performs irreversible deletion but its user-facing description is a minimal 'Delete a QR code' with no warning, confirmation, or friction. In an agent setting, ambiguous destructive tools can be invoked accidentally or through prompt manipulation, causing permanent loss of configuration or assets.
The delete_recipient tool can remove one or many saved recipient addresses, yet the interface does not clearly communicate permanence or require confirmation for batch deletion. Because address-book entries are sensitive operational data, accidental or manipulated invocation can disrupt mailing workflows and cause loss of recipient records.
The delete_sender tool permanently removes saved sender/return addresses without any explicit warning or confirmation semantics. Loss of sender addresses can break fulfillment workflows and may be triggered unintentionally by an autonomous agent that does not appreciate the destructive nature of the operation.
The send_order tool triggers real-world effects: it spends account resources and causes physical mail to be sent to recipients, potentially at scale. Without explicit confirmation language or execution safeguards, an agent could be induced to place unwanted orders, leak sensitive message/address data to a third party, or incur financial and reputational harm through accidental mailing.
The basket_send tool submits all queued orders for live processing, which can amplify mistakes because a single call may trigger multiple real mailings and charges. Although testMode exists, the tool does not make safe default behavior explicit, so an agent may execute a production send without presenting the user with the operational and financial consequences.
The delete_custom_image tool removes uploaded design assets with no explicit indication that the action is irreversible or may affect dependent custom cards. In an agent workflow, this can lead to unintended asset loss and broken card designs if the deletion is performed speculatively or under prompt confusion.
The delete_custom_card tool permanently deletes a custom card design without warning or confirmation. Because custom designs may represent business-critical templates, accidental invocation by an AI agent can result in operational disruption and loss of work product.
The calculate_targets tool adds geographic prospecting functionality that is not necessary for basic note-sending and expands the skill into lead-generation and location-based targeting. In this context, that extra capability increases abuse potential because an assistant authorized to send mail can also be used to profile or target geographic areas without that power being clearly implied by the skill's stated purpose.
This manifest file includes a high-level description of sending handwritten notes via AI assistants, but it does not specify any concrete trigger phrases, scope boundaries, or exclusion conditions. In manifest files, such broad capability descriptions can contribute to ambiguous activation behavior if used by tooling to infer when the skill should be invoked.
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"prepublishOnly": "npm run build"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.12.1",
"handwrytten": "^1.0.0",
"zod": "^3.24.4"
},
The manifest allows a floating @modelcontextprotocol/sdk version while known advisories exist for this package family, including issues relevant to MCP servers such as cross-client data leakage and DNS rebinding protections. Because this skill handles user content and may connect agents to external actions, inability to verify the resolved SDK version meaningfully increases the risk of deploying a vulnerable build.
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.12.1",
"handwrytten": "^1.0.0",
"zod": "^3.24.4"
},
"devDependencies": {
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"dependencies": {
"@modelcontextprotocol/sdk": "^1.12.1",
"handwrytten": "^1.0.0",
"zod": "^3.24.4"
},
"devDependencies": {
"@types/node": "^22.15.3",
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"zod": "^3.24.4"
},
"devDependencies": {
"@types/node": "^22.15.3",
"tsup": "^8.4.0",
"tsx": "^4.19.4",
"typescript": "^5.8.3"
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
},
"devDependencies": {
"@types/node": "^22.15.3",
"tsup": "^8.4.0",
"tsx": "^4.19.4",
"typescript": "^5.8.3"
},
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"devDependencies": {
"@types/node": "^22.15.3",
"tsup": "^8.4.0",
"tsx": "^4.19.4",
"typescript": "^5.8.3"
},
"engines": {
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"@types/node": "^22.15.3",
"tsup": "^8.4.0",
"tsx": "^4.19.4",
"typescript": "^5.8.3"
},
"engines": {
"node": ">=18.0.0"