Back to skill

Security audit

Stripe Production Engineering

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Stripe integration guide, but it includes unsafe payment idempotency examples and broad production-impacting commands that warrant review before use.

Review and correct the idempotency patterns before using this skill to generate production Stripe code. Require explicit test/live environment selection, user confirmation for account-changing actions, and stable persisted order or usage-batch IDs for all mutating Stripe API calls.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:136
Finding

Timestamp-Based Checkout Idempotency Key Allows Duplicate Checkout Sessions

Content
View full analysis
; }) { const session = await stripe.checkout.sessions.create({ customer: params.customerId, mode: params.mode, line_items: [{ price: params.priceId, quantity: 1 }], success_url: `${params.successUrl}?session_id={CHECKOUT_SESSION_ID}`, cancel_url: params.cancelUrl, metadata: params.metadata ?? {}, // Recommended defaults allow_promotion_codes: true, billing_address_collection: 'auto', tax_id_collection: { enabled: true }, customer_update: { address: 'auto', name: 'auto' }, payment_method_types: ['card'], // For subscriptions ...(params.mode === 'subscription' && { subscription_data: { metadata: params.metadata ?? {}, trial_period_days: 14, }, }), }, { idempotencyKey: `checkout_${params.customerId}_${params.priceId}_${Date.now()}`, }); return session; } ``` ### Technical Analysis Stripe idempotency only works when every retry of the same logical operation uses exactly the same idempotency key. Incorporating `Date.now()` creates a different key each time the function is invoked. Consequently, Stripe treats retries as independent requests rather than returning the result of the original request. The key also lacks a stable order or transaction identifier. Two legitimate purchases of the same price by the same customer cannot be distinguished using business-operation identity, while retries cannot be reliably correlated with the original request. This directly conflicts with the Skill's stated requirement that all mutating API calls be idempotent. ### A ...[truncated 1159 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:175
Finding

Timestamp-Based PaymentIntent Idempotency Key Can Cause Duplicate Payment Attempts

Content
View full analysis
; }) { return stripe.paymentIntents.create({ customer: params.customerId, amount: params.amount, currency: params.currency, automatic_payment_methods: { enabled: true }, metadata: { ...params.metadata, created_at: new Date().toISOString(), }, }, { idempotencyKey: `pi_${params.customerId}_${params.amount}_${Date.now()}`, }); } ``` ### Technical Analysis The timestamp causes every invocation to use a unique idempotency key, including invocations that are retries of the same purchase. Stripe therefore creates a new PaymentIntent instead of returning the original PaymentIntent. Using only the customer and amount as the semantic portion of the key is also insufficient. A customer may legitimately make multiple purchases for the same amount, so idempotency must be tied to a unique order or transaction rather than mutable request timing. The embedded `created_at` metadata also changes on every invocation, reinforcing that retried requests are represented as separate payment objects rather than one stable business operation. ### Attack Path 1. An application implements the supplied `createPaymentIntent` function. 2. A payment request reaches the server and Stripe creates a PaymentIntent. 3. The original response is delayed or lost, or the user deliberately submits the request again. 4. The application retries the operation. 5. The new timestamp produces a different idempotency key. 6. Stripe creates another PaymentIntent for the same customer and amount. 7. If the application or client confirms more than one resulting PaymentIntent, multiple payment attempts ...[truncated 583 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:297
Finding

Timestamp-Based Usage Record Idempotency Key Allows Duplicate Billing Records

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill exposes very broad natural-language commands such as 'Set up Stripe checkout', 'Configure webhooks', and 'Go-live checklist' without any explicit scoping, confirmation, or environment constraints. In an agent setting, this increases the chance of unintended invocation or overbroad execution, especially for production-impacting payment and billing tasks, which could lead to unsafe changes or disclosure of sensitive operational guidance.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.