Skip to content

SEC-768: Send card details to Stripe in the request body, not the URL - #380

Draft
msuitcase wants to merge 1 commit into
masterfrom
security/SEC-768-stripe-card-details-in-body
Draft

msuitcase wants to merge 1 commit into
masterfrom
security/SEC-768-stripe-card-details-in-body

Conversation

@msuitcase

@msuitcase msuitcase commented Sep 18, 2026

Copy link
Copy Markdown

Description

ReferralCustomerService.createStripeToken builds the POST https://api.stripe.com/v1/tokens request with card[number], card[exp_month], card[exp_year] and card[cvc] appended to the URL query string. It calls setDoOutput(true) but never writes a body. Query strings are routinely captured by access logs, outbound proxies, APM/tracing tools and Referer headers, so cardholder data could be retained outside the payment path (PCI DSS requirement 3 / 4).

This change writes the same form-encoded string to the connection's output stream and drops it from the URL. Stripe already expects application/x-www-form-urlencoded bodies on this endpoint (it is what easypost-ruby, easypost-go and easypost-csharp do today), so there is no behavioural change for callers. InternalUtilities.getEncodedURL is reused unchanged as the encoder.

Also adds a Next Release CHANGELOG entry.

Tracking: SEC-768 (internal).

Testing

  • No Maven on the machine I authored this from, so this has not been compiled here; the change is a new java.io.OutputStream import, one renamed local, and a try-with-resources write. Please run mvn test / checkstyle in CI.
  • Cassette re-record needed: src/test/cassettes/referral_customer/referral_add_credit_card.json and create_bad_stripe_token.json were recorded with the card fields in the URL, and TestUtils configures EasyVCR to match byFullUrl().byBody(...), so testReferralAddCreditCard and testCreateBadStripeToken will not replay until re-recorded with the partner / referral prod keys. I do not have those keys. When re-recording, please confirm the recorded URL no longer carries card fields and that the body censor rules cover card[number] and card[cvc].

Pull Request Type

Please select the option(s) that are relevant to this PR.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Improvement (fixing a typo, updating readme, renaming a variable name, etc)

🤖 Generated with Claude Code

`referralCustomer.addCreditCardToUser` built the `POST /v1/tokens` request
with the card number, expiry and CVC in the URL query string and never wrote
a request body (despite `setDoOutput(true)`). Stripe accepts the same
form-encoded fields in the request body, which keeps cardholder data out of
access logs, proxy logs, tracing tools and Referer headers.

SEC-768

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant