Quick question: On the scale of severity when there’s a breach and a totally botched response, what comes after “dumpster fire?” Towering inferno? When Brian Krebs wrote that the Equifax debacle was a dumpster fire, he probably knew, based on years of experience, that more bad news would come to light. But he probably didn't know the specfics. Sure enough, more bad news came and it’s another reminder of why rate limits are so incredibly important for websites and APIs. It’s also interesting to point out some of the subtle differences in the way the same exact process is implemented by different companies. Can anything be learned?
In my last post about how not to become the next Equifax, I also offered a bit of personal advice that had to do with adding a security freeze to your social security number at each of the three major credit reporting bureaus; Equifax, Experian, and Transunion.
Security freezes are pretty straightforward. Once you’ve enabled a freeze on your social security number at each of the big three agencies, pretty much any process that requires a credit check will fail. For example, a lot of identity theft involves the fraudulent opening of financial accounts (bank accounts, credit cards, loans, etc.). When a freeze across the big three is in place, those accounts cannot be opened because the credit checks hit a brick wall and cannot be completed. The only way around the brick wall is to lift the freezes (presumabley something only you should be able to do for your social security number). A freeze can be lifted indefinitely, between two specific dates, or just for one party such as a specfic financial institution. For example, if you’re applying for a car loan with Bank of America, you can lift the freeze for Bank of America only.
When you put the freezes in place, each of the agencies issues a secret PIN that you must provide whenever you want to suspend those freezes. However, as reported on Twitter by Tony Webster and confirmed elsewhere, Equifax’s secret PINs were nothing more than a date and timestamp of when you made the freeze. Webster tweeted "If you froze your credit today [Sept 8 2017 at] 2:15pm ET for example, you'd get PIN 0908171415.” Once Equifax learned of the oversight, the company apparently converted to random number generation which could be equally problematic depending on implementation. But for consumers who established their freezes before the random number generator was installed, changing a PIN to something different from the original timestamp requires written correspondence to Equifax.
So what’s the big deal?
When news of the breach first came out, one of the very first questions that many people asked had to do with their secret PIN. The company did not disclose whether freeze PINs were included in clear text along with the other personally identifiable information (PII) that was released in the breach. If they’ve been disclosed, then the hackers could technically have what they need in order to unfreeze frozen records (provided Equifax doesn’t put some other countermeasures in place). The hope was and is that, best case scenario, the PINs were not disclosed. Or, in the almost-worst case scenario, if they were disclosed, the hope is that they were encrypted (which connects with one of the recommendations from my first Equifax post about encrypting data in transit and at rest).
But now, with the revelation that Equifax’s freeze PINs were nothing more than date and timestamps, things are a bit different because the secret PINs are no longer secret. If you’ve frozen your credit with Equifax, your PIN is now very easy to guess (the same is true if, as Webster reports, the timestamp was replaced with a randomly generated 10 digit number, but that's a different story for a different day). In either case, it would only take a few lines of code to loop through all the possibilities.
While it’s one thing to write some code that loops through all the possibilities, it’s an entirely different thing to feed those guesses into Equifax’s web-based unfreezing process. Recall from my first post regarding the Equifax breach that hackers love scale. And, they love APIs because they typically scale so well. APIs are the equivalent of spoon-feeding Pop Rocks to hackers on Jolt Cola. But even if there is no API into Equifax’s web-based unfreezing process, it doesn’t matter because of how trivial it is for hackers to essentially create one of their own. Their process typically "scrapes" the fields off a web page and turns the result into a programmable interface that's just like an API; a technique sometimes called “ScrAPI” (pronounced scrape-pea-eye). And this is also where the next opportunity to stop those hackers dead in their tracks comes into play: rate limiting.
Equifax’s web-based unfreezing process (what developers often call a workflow) claims to involve three steps. However, when I last checked, the user interface incorrectly mapped the step numbers to the pages involved in the workflow (an example of Equifax’s lack of attention to detail). Each page involves a form and both the second and third page in the workflow identify themselves as “Step 2.”
The first step (the first form, pictured below) requires the user to enter a bunch of easily discoverable personal information such as first and last name, social security number, address, and oddly, an optional former address with no tips on why you’d bother to fill it in. The social security number isn’t masked the way Experian’s page for the same purpose does it (with an option to unmask). But another key difference involves Equifax’s use of a captcha field to ensure that the user of the page is a human and is not a script written by a hacker. Theoretically, only humans can interact with captchas. Experian’s first page does not involve a captcha. Bearing in mind that captcha technology has proven fallible in the past, one has to assume that an expertly written script (sometimes called a “bot”) backed by a file of legitimate names, addresses, birthdates, and social security numbers, could complete the form and make it to the second step.
In step two of Equifax’s unfreezing process, you are presented with a very simple form to tell the system what you want to do. As shown below, the choices are to temporarily lift the freeze by date range or specific party or to permanently lift the freeze altogether. It would be trivial for a bot to complete this page and move on to the third step.
Depending on the type of “lift,” the third page asks for additional details and your secret PIN. The example below asks for a date range because in my test of the process, I elected to temporarily lift the freeze for a period of time.
This is where using a timestamp as the secret PIN could be problematic. Or even just a string of ten randomly selected digits. The reason is that a bot would have no trouble trying all the possibilities on relatively short order unless….. unless the people who built this workflow put rate limits on this page. Without rate limiting, a bot could try every possibility, “pressing" the submit button each time, until it achieved success (provided some other intrusion detection system didn’t spot the unusual number of failed attempts, alerting security personnel to the situation). But with rate limiting — like when a process automatically rejects additional attempts after three fails (whether it's a bot or a human) — a bot would have a very difficult time trying all the possibilities without having to constantly restart the entire process.
I personally restarted the process several times and, as can be seen from the screenshot below, the system prevented me from going any further after the third attempt. If it was in fact rate limiting that stopped me and not some other system error (the message doesn’t say), the same rate limiting would have stopped a bot dead in its tracks. Of interesting note, the error message refers users to the other two credit reporting agencies (aka: the competition!).
While an API wasn’t explicitly in use in this situation, we should always keep in mind that where an API doesn’t exist, hackers will essentially create one in order to scale their attack against your interface. That’s because there’s pretty much no such thing as a human interface that isn’t also an application programming interface. In fact, the grand majority of RESTful web APIs involve an interface that’s minimally different, if at all, from a web form built for humans.
Furthermore, the same rate limiting vigilance that applies to interfaces intended for humans applies to your intentionally provisioned APIs as well. And finally, there’s always one other “rate limit” that stops hackers in their tracks: money. Although Equifax didn’t confront me with a paywall to finish lifting the freeze, you can imagine how it wouldn’t have to charge much in order to discourage would-be hackers. For example, if there was a just a $1 fee (and cryptocurrency was not an accepted form of payment), scaling the attack would risk too much of a financial loss, never mind the money trail that gets left behind.