T09 · Insecure Skill Coding Practices
- Location
handler.js:338- Finding
Destructive callback routes can bypass confirmation workflows
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Gumroad admin skill appears purpose-built rather than malicious, but it can perform live refunds, deletions, and license changes with weak safeguards.
Install only if you trust this publisher with a live Gumroad merchant token. Use a dedicated Gumroad token, avoid configuring a generic API_KEY, and be careful with refunds, deletions, license changes, custom fields, and customer/shipping data because the current handler does not strongly enforce confirmation for every high-impact action.
handler.js:338Destructive callback routes can bypass confirmation workflows
handler.js:6Generic API_KEY fallback may disclose an unrelated ambient credential
Referenced artifact was not completely inspected
1. **PRIORITIZE HANDLER**: Always attempt to use the interactive button-based GUI (handled by `handler.js`) for the best merchant experience.
Referenced artifact was not completely inspected
1. **PRIORITIZE HANDLER**: Always attempt to use the interactive button-based GUI (handled by `handler.js`) for the best merchant experience.
Referenced artifact was not completely inspected
2. **CLI AS FALLBACK**: Only use `scripts/gumroad-pro.js` via the CLI for complex data retrieval or specific actions not available in the GUI.
Referenced artifact was not completely inspected
2. **CLI AS FALLBACK**: Only use `scripts/gumroad-pro.js` via the CLI for complex data retrieval or specific actions not available in the GUI.
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.
if (!text || !text.startsWith('gp:')) return next();
// --- NAVIGATION (Always Clear State) ---
if (text === 'gp:main' || text === 'gp:products' || text === 'gp:sales' || text === 'gp:payouts' || text === 'gp:subs' || text === 'gp:whoami') {
delete ctx.session.gpPendingInput;
}
The script retrieves and prints full shipping address data, including recipient name, street address, city, ZIP/postal code, and country, directly to stdout. This is highly sensitive personal information, and in an agent-driven environment it can be leaked into prompts, logs, telemetry, or responses without a strong business need for routine display.
The skill requests access to sensitive environment variables containing Gumroad credentials, but it does not declare an explicit tool scope such as permissions or allowed-tools. In a skill that can process refunds, delete products, manage licenses, and access merchant data, this weakens least-privilege boundaries and can enable unintended credential exposure or unauthorized actions if the platform grants broader execution than expected.
The skill advertises destructive merchant actions such as deleting products and processing refunds without an explicit warning, confirmation requirement, or mention of irreversible consequences. In the Gumroad merchant context, accidental invocation could directly cause financial loss, inventory disruption, or customer-impacting account changes, especially because the skill is designed for high-privilege operational workflows.
The manifest describes webhook management as part of the skill's purpose, but the code also exposes a separate subscribers resource and retrieves subscriber profile details via /subscribers/{id}. Accessing subscriber account/profile information is not described in the manifest, which frames this area as managing store webhooks rather than inspecting subscription subscriber records.
Custom field deletion is performed immediately with no warning or confirmation. Because checkout fields affect data collection during purchases, accidental deletion can disrupt order flows, compliance-related data capture, or downstream fulfillment processes.
The skill decrements a license usage count immediately after a single action without any confirmation dialog or safety interlock. In this context, that can alter customer entitlements and support state, and accidental activation is plausible because the skill exposes high-impact merchant operations through compact callback actions.
The API reference prominently includes destructive and irreversible operations such as delete, refund, disable, rotate, decrement, and webhook changes, but provides no warnings, confirmation guidance, or safe-usage constraints. In an agent context, this increases the chance of accidental high-impact actions against live merchant data, customer transactions, licenses, discounts, and webhooks due to ambiguous or over-broad user requests.
The manifest description limits the skill to managing Products, Sales, Licenses, Discounts, Payouts, and Webhooks, but this reference adds a separate Custom Fields capability for listing, creating, and deleting product fields. That expands the documented behavior beyond the declared skill purpose rather than serving as an obvious implementation detail of the listed features.
The guide explicitly tells an agent to invoke the skill from a vague 'general prompt' such as opening the dashboard, rather than requiring a clear, scoped user intent. In a high-privilege merchant-management skill that can process refunds, shipping, licenses, discounts, and webhooks, broad activation increases the chance of unintended tool use and cross-skill hijacking from ambiguous user messages.
The sales listing and detail flows print customer email addresses and purchase metadata directly to stdout, which can expose personal data to chat transcripts, shell history capture, logs, or downstream tools. In an agent skill context, this is more dangerous because the model may surface or repeat this data unnecessarily outside the minimum needed task scope.
The manifest description presents a fairly specific scope centered on merchant operations for products, sales, licenses, discounts, payouts, and webhooks. This file goes beyond that scope by implementing additional account and catalog-management capabilities such as subscriber lookup, subscription enumeration, variant/custom-field administration, and user profile retrieval that are not mentioned in the manifest.
The manifest claims comprehensive management for Products, Sales, Licenses, Discounts, Payouts, and Webhooks, but the implementation also lists variant categories, variants, and creates/deletes custom fields. Those capabilities go beyond the enumerated resource scope in the manifest, even though they are adjacent to product management.
The account view injects an unrelated external GitHub link into a privileged merchant-management skill. Even though it is not direct code execution, mixing operational UI with promotional links increases phishing and trust-confusion risk, especially in an admin workflow where users may assume all links are platform-relevant and safe.
The UI text addresses the user as "Sir" and similar honorific language throughout the skill, imposing a specific style of address without giving the user a choice. This can violate language/locale or communication-style policy expectations when users have not opted into that phrasing.
The script reads authentication credentials from GUMROAD_ACCESS_TOKEN or API_KEY, but the file provides no explanatory comment or warning about the use of secrets for authenticating outbound API requests. Although it errors when missing, it does not disclose secret usage or handling expectations to the user.
The inline comment states that the published field is not the correct way to toggle status in the Gumroad API and the code only sends name/price/description/url in products update. However, the usage text later tells users they can pass --published true|false, which contradicts the actual implemented behavior.
Fetching the authenticated Gumroad user profile is not one of the manifest's stated use cases, which focus on inventory, transactions, licenses, discounts, payouts, and webhooks. While adjacent to the integration, this capability is not clearly necessary for the declared purpose and broadens access to account-level information.
No suspicious patterns detected.