T09 · Insecure Skill Coding Practices
Error
- Location
- src/cli.ts:184
- Finding
- Payment card credentials exposed through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `src/cli.ts:184-216` **Vulnerability Type**: Sensitive payment data exposure through process arguments **Risk Level**: High ### Vulnerable Code ```ts program .command("buy") .description("Buy a product") .argument("<selva_id>", "Selva product id") .requiredOption("--method <method>", "Payment method: card|saved") .option("--number <card_number>", "Card number for --method card") .option("--exp <exp>", "Card expiry MM/YY for --method card") .option("--cvv <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 <num> --exp <MM/YY> --cvv <code> ``` ### 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
- <![CDATA[ ## Remediation Suggestions 1. Remove `--number`, `--exp`, and `--cvv` command-line options. 2. Prefer the existing Stripe-hosted settings-page flow so payment credentials are collected in a processor-controlled interface. 3. If terminal-based collection is unavoidable, use an interactive prompt that: - Disables terminal echo. - Reads payment fields from standard input rather than process arguments. - Prevents values from entering shell history. - Avoids logs, telemetry, crash reports, and error messages containing the input. 4. Keep card data only for the minimum time needed to tokenize it, then remove references promptly. 5. Never persist or return the raw Stripe response unless required; return only the token and minimal non-sensitive metadata. 6. Add tests confirming that payment credentials cannot be supplied through command-line arguments or printed in output. 7. Update `README.md` and `SKILL.md` to direct users exclusively to a secure hosted or interactive card-entry workflow. ]]>
