Skip to main content

Breaking Credit Card Tokenization – Part 3

January 07, 2016

In the first two installments of this blog series I addressed the core terms and history of credit card tokenization systems before digging into some attacks. Please read part one and part two to get up to speed on general terms and background information before digging into new attacks discussed in this post.

Side Channels

The previous post in this blog discussed timing side channel attacks on credit card tokenization systems. This post will investigate the following side channel attacks:

  1. Credit cards saved to user profiles in an e-commerce application
  2. Helpful HTTP headers in RESTful credit card tokenization services

My Profile Side Channel Attacks

Many commerce apps—especially ones using credit card tokenization—implement a “My Profile” type feature in which the customer can save a form of payment for future reuse.  If an attacker can take over a customer’s account or session (e.g. by stealing credentials or if the application switches between HTTP and HTTPS with the same session cookies making MITM possible), then the attacker can browse to the “My Saved Credit Cards” page, observe truncated PAN data, and then proceed to add new credit cards to the user account’s profile, analyzing the responses.  

For example, suppose Alice, a user on the e-commerce site, has three saved credit cards in her user profile, and an attacker who has stolen her session or credentials can observe the following:

Visa ending in 1111Exp 12/17Alice Smith
123 Smith St
Beverly Hills, CA 90210

MasterCard ending in 1324Exp 11/19Alice Smith
123 Smith St
Beverly Hills, CA 90210

American Express ending in 4993Exp 04/18Alice Smith
Smith Enterprises
456 Smith Ave
New York, NY 10001

This metadata is not quite as helpful as the data a malicious insider in the first post in this series may have, but it is still enough to hone in on specific attacks. All of the potential credit card prefixes for Visa, MasterCard, and American Express are open source knowledge for a given target country. An attacker can use this information to generate a list of potential PANs that match this very truncated version, and, one at a time, attempt to add them to Alice’s profile. If a fourth payment method is on the list, then the attacker did not discover one of Alice’s credit cards. However, if the number of payment methods stays the same, then the attacker just discovered one of Alice’s credit cards. The following pseudo-code illustrates the algorithm (award bonus points for deleting the bogus credit card that didn’t match what the application already had in the database):

def findPan(truncatedPan):
    pans = generatePansFromTruncation(truncatedPan)
    count = countCCsInProfile()
    foreach pan in pans:
        newCount = countCCsInProfile()
        if (count == newCount):
            return pan // Hit!

Behind the scenes, this is another example of developers doing what they are trained to do: be efficient. If a credit card tokenization record already exists, then adding a duplicate violates the efficiency rules developers are taught. Thus, another side channel attack is discovered.

Preventing My Profile Attacks

The fix to this, like the fix in the second post in this series, is to intentionally introduce some inefficiency in the application in lieu of creating a mechanism to extract a Boolean true/false response whether a credit card already exists. A suggestion we often provide to developers is to return a new payment method ID or token even if the credit card matches a record already in the database.

Helpful Header Side Channels

Some developers who really like REST can be downright fanatical about RESTful design requirements, splitting hairs over whether a particular implementation is truly RESTful or not.  Many large development teams have at least one of these “RESTful service geeks” (my moniker for them), but do not let them design your RESTful credit card tokenization service.  Consider the following tokenization request from the first post in this series:

POST /api/generateCcToken HTTP/1.1
Connection: keep-alive
Accept: */*
Content-Type: application/json
Content-Length: 161


A RESTful service geek will instruct developers that HTTP status codes should be very distinct. For example, the service might return the following response:

HTTP/1.1 201 Created
Content-Type: application/json 

Or perhaps this:

HTTP/1.1 202 Accepted
Content-Type: application/json 

Something as small as “201” versus “202” can indicate a world of contextual difference. An attacker will likely learn that “201 Created” means the credit card in the tokenization request has not previously been seen by the tokenization system, so the system created a brand new credit card token record for it. Likewise, an attacker might decipher “202 Accepted” as an indication that the credit card already exists on the system. Or perhaps there are custom HTTP headers that are added or updated on the service’s response (which may especially be true if the service is designed for the consumption by a mobile application where developers think nobody will ever be able to see those headers).  Any of these can be enough of a signal, no matter how subtle—just take the blinders off and look carefully at every detail. We have seen this attack’s cousin for years now: web applications that are kind enough to tell us if a user account already exists at registration or during an attempt to remember a user ID or password.  

This insight, coupled with the scenarios already presented in this series where an attacker may know truncated PANs and billing information, can also lead to credit card exfiltration.

Preventing Header Side Channel Attacks

Successful applications will always respond the same way regardless of the internal differences.  It’s boring and probably doesn’t comply with all of the RESTful principles, but at the same time it protects knowledge of the presence of certain credit cards stored in the system. The following is a nice safe response:

HTTP/1.1 200 OK
Content-Type: application/json 

Stay Tuned

Stay tuned for more attacks against credit card tokenization systems in the rest of this blog series.

Read part 4.

Related Blogs

December 09, 2015

Breaking Credit Card Tokenization – Part 1

This is the first in a series of blog posts on the topic of breaking credit card tokenization systems and is the written version of several conference...

See Details

January 05, 2016

Breaking Credit Card Tokenization – Part 2

Side channels are unintended ways information can be observed in a system. Attackers can leverage side channels to make software divulge details that ...

See Details

January 21, 2016

Breaking Credit Card Tokenization – Part 4

Remember that the main point of credit card tokenization is to keep PANs (Primary Account Numbers) out of the main application-hosting environment. Me...

See Details

How Can We Help?

Let us know what you need, and we will have an Optiv professional contact you shortly.

Privacy Policy

Related Insights

December 16, 2011

PCI DSS and the Network Diagram

This post is designed to give a high level overview of what should be included in a network diagram and how to incorporate simple data flow indicators...

See Details

March 29, 2017

Attack and Penetration Services

Learn how our experts work to expose weakness to validate your security program.

See Details

Stay in the Know

For all the latest cybersecurity and Optiv news, subscribe to our blog and connect with us on Social.


Join our Email List

We take your privacy seriously and promise never to share your email with anyone.

Stay Connected

Find cyber security Events in your area.