Resolving a security issue in test mode
If you are in the e-commerce business, then you have probably heard of Stripe. Stripe is a global payments provider with a fantastic SDK and web integrations platform. If you are running any sort of online checkouts, subscription services, contract automation, etc – Stripe is definitely worth looking into if you are not already using them.
I was helping out a family member recently who was moving their website from one platform to another. They were using Stripe as their existing payments provider, and had no intention on changing anything there.
When it came to testing and validating some of the automations that had been migrated, we received a security notice from Stripe almost immediately. Now, I am no Stripe (or payments for that matter) expert. I began researching “tokenization” within Stripe to better understand what was possibly going on.
At a high level, Stripe’s tokenization method is meant to ensure their clients maintain PCI compliancy, as well as protect cardholder data should it become compromised. When a business collects card information, it must first request a unique “token” from stripe. This token is specific to the card/cardholder and can only be requested, and subsequently used, by that particular business. When the time comes to process the payment, the business will simply pass this token to Stripe, in lieu of the actual card number, and payment will be processed. Should this token ever become compromised, it will not be able to be used by anyone other than the business who originally requested it. If you are interested in further detail on this topic, you can find it here.
Unfortunately, I did not have access to the underlying web server or code for this customer’s site. I had previously assisted on some backend process automation, and was just trying to validate everything would still work with this new website. So when it came to fixing the issue, I was reliant on the web developers & hosting company.
Initially their hypothesis was the issue must be caused by having the payments portal in “test” mode. However, when I disabled test mode and attempted to place a live order, I saw the same behavior. I opened Chrome developer tools and began doing a stare-and-compare of the two websites and how their payment portals behaved. What I learned with the old site, which I’ll call the “working instance”, was it was behaving exactly like the tokenization documents had explained:
1. Payment portal calls the tokens API, and passes cardholder information:
2. Tokens API responds back with the token value that can be used to process this customer’s card
3. Payment portal calls the payments API and passes the token. Does not include the full cardholder data.
With the new site, there was no token request.
Instead the site was attempting to send the full cardholder data to Stripe directly. This means in the current design, my client was basically saving the cardholder data and would be responsible for ensuring they were doing so in a PCI compliant manner.
With tokenization, this all becomes anonymized, and they are not storing any actual card data. Also, with tokenization, should my client need to process further payment, this would be done in a secure manner as Stripe’s built-in fraud protection would be able to identify that this card information was originally entered in directly by the cardholder via the online portal.
Along the way, we discovered a few security flaws in the new website itself, also related to payments, and ultimately recommended an architecture review to determine the best path forward. The last thing this person needed was a payments breach on their hands. Thankfully, Stripe proactively notified us of security flaws in the new system which led to the discovery of other security gaps on the platform. Once we remediate these outstanding issues, we can then make sure their custom automation tools perform as expected!