P.F. Chang’s Security Flaw revealed, following Panera Bread’s leak
Disclaimer: This article contains a firsthand vulnerability discovery and is intended for educational and security awareness purposes only. Do not attempt to violate any laws in your jurisdiction, or make use of this knowledge for malicious purposes — doing so would be unethical and of course, illegal. I hereby waive any personal responsibility and liability in the form of injury, damage or any consequences arising from your actions, should you get yourself “in trouble” by attempting to do anything unlawful or otherwise. This vulnerability is being disclosed ethically and the timeline can be referred to at the bottom of this article.
Note: The Proof of Concept (PoC) has been constructed by creating “test” accounts for simulating exploitation of the improper access control. Doing so keeps it legal — we are essentially reading from/writing to the accounts we actually (should) have access to, using the member website. This also prevents any other member accounts from being accidentally read, affected or overwritten. A detailed vulnerability disclosure report, embedded as a Google Docs page can be viewed below.
The morning of April 4th, I woke up to news reports of Panera’s Bread security flaw and the possible data exposure it could have caused, as featured on Krebs on Security, Dylan Houlihan’s original post, and numerous other news sites.
Little did I know, merely 2 days after Panera Bread’s public disclosure took place, would I be discovering a similar and equally serious vulnerability on one of my favorite restaurant chains’ website — P.F. Chang’s. They have the best Dali Chicken and Kung Pao entrées, hands down. But you’d think they would have even better security after the 2014 credit card breach.
Their website proves otherwise. I remember not too long ago P.F. Chang’s Rewards website got an appealing redesign. However, there appears to be a serious flaw existing beneath the beautiful, thematic pages of their Rewards website.
The Rewards website uses 2 APIs — a “Conductor” API to retrieve Rewards member records (
https://conductor.pfchangs.com ) and “Soil” API (
https://soil.pfchangs.com ) giving access to restaurant location data and mostly public information. For the purposes of our demonstration, we are only focused on the Conductor API.
For the attack to work, it is sufficient to sign up for a P.F. Chang’s Rewards account using a rogue e-mail account. In my case, I simply used firstname.lastname@example.org and variants (e.g. email@example.com, rogue3…etc.) to register for Rewards accounts. Yes, they accepted the email as valid — no email verification needed either. Using the rogue email address, the attacker can sign into the Rewards website and pay close attention to the network API calls being made, along with the content of the HTTP headers.
Two such HTTP headers include
These are apparently the authentication headers giving you access to your Rewards account and the goldmine — the improperly authenticated API.
If you take a closer look at the network requests and the HTTP headers, it appears that a particular API endpoint is called quite frequently, as soon as you are logged in.
Notice the GET parameter being used to identify the user whose information is being requested: it’s their email. Of course, because you are logged in right now, it is displaying, and making use of your (rogue) email address to obtain the JSON record with your information:
A simple replacement of this email with any other customer’s email will return the personal information of that P.F Chang’s Rewards member.
This information includes:
- Full Name
- Partial Date of Birth (DOB) as MM/DD (YYYY was always set to 1924 — they don’t store or seem to care about the year)
- Phone Number
- Home Address
- List of orders placed by the user, including the yummy dishes
- Price paid for each item in the order, along with other information
- Payment method (if available) — in all cases, I observed “null” being returned. After all, it’s probably smart if the API purposely does not keep any payment information.
- Last selected store ID (most likely the same as the frequently visited store)
- P.F. Chang’s Rewards / Loyalty # of the member
Using some digging into public records or data dumps, any skilled attacker may be able to cross-reference C-level executive records with the Rewards website to obtain, at the very least, their personal phone number, birthday, etc.— after all, good chance that the company employees and executives take part in their very own Rewards program too!
At this time, there is no indication that any records contained on the Rewards website were exposed or overwritten by anyone, maliciously — but I simply wouldn’t know the answer to that, only P.F. Chang’s would.
Note: You would still need “token” and “authorization” headers to access the API — which you can obtain from creating a rogue account, however, after that first step the API does not discriminate between whose record is being accessed and if they are the one who is actually logged in.
Given below are the steps to reproduce the vulnerability exploit.
- Sign up for P.F. Chang’s Rewards program
2. Log in to the account and pay attention to the network requests — most notably the resource name ending in your email.
3. Replicate the request with the
token and other headers present in the HTTP Request but this time, replace the email present in the API endpoint URL with your victim’s email address (the victim must be a P.F. Chang’s Rewards member)
The request will therefore now have to be sent to:
4. Relish the information returned.
It is vital to note that during this entire process firstname.lastname@example.org was logged into the account and yet is able to access **akshay**@**** (my personal account’s) information.
Part 2. Overwriting Arbitrary Member Accounts
Yes, there’s a Part 2 to this…
The API’s Improper Access control also enables one Rewards member to overwrite another arbitrary or targeted Rewards member account’s information with theirs — for example, to claim their rewards when at a restaurant. All one needs to “redeem” the rewards at a restaurant is to use a member’s phone number when signing the check or before placing the order. For this part of the attack to work, one doesn’t even need an email address.
But I’ll leave you with the detailed 14-page report here to dig deeper: https://docs.google.com/document/d/11DtVDXkw0hMn0kQCy8uIANeEnMGn-E3zXEpAFX-3b7I/edit
- Apr 4th, 2018: Security flaw is identified incidental to the regular use of P.F. Chang’s Rewards website.
- Apr 4th, 2018: Within a few hours of discovery, P.F. Chang’s is immediately notified via email about a “serious security vulnerability” at email@example.com email address, as specified in their Privacy/Terms pages. The courtesy email requests P.F. Chang’s to provide me with the right person/email address to reach out to, for disclosing further information regarding the vulnerability. A grace period of 30 days is specified by me — given the lessons we learned from Panera Bread, in which the security researcher, Dylan Houlihan waited 8 months with no luck.
- Apr 6th, 2018: P.F. Chang’s China Bistro, Inc. responded via their “firstname.lastname@example.org” email address, requesting more information.
- Apr 7th 2018: Detailed vulnerability disclosure report prepared ( https://docs.google.com/document/d/11DtVDXkw0hMn0kQCy8uIANeEnMGn-E3zXEpAFX-3b7I/edit?usp=sharing ) and emailed privately to P.F. Chang’s for review, within ~12 hours of receiving their request.
- Apr 7th 2018: The Rewards website’s “Conductor” API appears to be down — either for periodic maintenance, internal bug hunting efforts, simply as a safety measure or due to a potential patch in progress. The API remains down for the entire weekend.
- Apr 9th 2018 ~5:30 AM: Verified the bug has been patched / no longer applicable and the Rewards system is back up. Any improper access requests to Conductor API now return a
"IsTokenValid":"Not Authenticated"response within the JSON.
Kudos to P.F. Chang’s for promptly addressing this flaw!
- Apr 9th 2018 10:00 AM: Public disclosure via Medium.
© 2018. Akshay Sharma.