T09 · Insecure Skill Coding Practices
- Location
src/cli.ts:184- Finding
Payment card credentials exposed through command-line arguments
- Content
View full analysis
", "Selva product id") .requiredOption("--method ", "Payment method: card|saved") .option("--number ", "Card number for --method card") .option("--exp ", "Card expiry MM/YY for --method card") .option("--cvv ", "Card CVV for --method card") .action( async ( selvaId: string, options: { method: string; number?: string; exp?: string; cvv?: string } ) => { const method = options.method === "saved" ? "saved" : options.method === "card" ? "card" : null; if (!method) { throw new Error("--method must be either 'card' or 'saved'."); } let paymentToken: string | undefined; if (method === "card") { if (!options.number || !options.exp || !options.cvv) { throw new Error("For --method card, provide --number, --exp, and --cvv."); } const stripeConfig = await stripePublishableKey(); const publishableKey = stripeConfig.stripe_publishable_key; if (!publishableKey) { throw new Error("Card tokenization requires STRIPE_PUBLISHABLE_KEY on the API."); } const tokenized = await tokenizeCard({ publishableKey, number: options.number, exp: options.exp, cvv: options.cvv }); ``` The same unsafe invocation pattern is explicitly documented at `SKILL.md:68`: ```text --method card --number --exp --cvv``` ### Technical Analysis The CLI accepts the full primary account number, expiration date, and CVV as command-line options. Although `src/stripe.ts` correctly sends these values directly to Stripe over HTTPS rather than to the Selva API, tokenization does not protect ...[truncated 1418 chars]- Remediation
View remediation
