Skip to content
BobDaHacker

BobDaHacker

bobdahacker.com July 19, 2026

I reported this on March 3rd, 2026. It is now June 16th. 105 days later. The critical vulnerabilities are still live. Frontier fixed the least important one and ghosted me on the rest. Your passport number is still leaking.

Someone posted their Frontier Airlines boarding pass on X. Unblurred. PNR and last name right there. But even if they'd blurred it, it wouldn't matter because the BCBP barcode on every boarding pass contains the PNR and last name in cleartext. Any barcode reader can decode it.

A real Frontier boarding pass posted publicly on X. The original poster blacked out their name and confirmation code, but left the barcode visible. I added the pink redactions.

Here's what most people don't know: the barcode on your boarding pass isn't just a random scanner thing. It's a BCBP (Bar Coded Boarding Pass) format defined by IATA. It contains your full name, PNR (booking confirmation code), flight details, and more, all in plaintext. Any barcode reader app on your phone can decode it in seconds. So even if you black out your name and confirmation number like this person did, the barcode gives it all away. Most people think they're being careful by hiding the text. They're not.

I wondered what you could do with just a PNR and a last name.

Turns out: everything. And I mean everything . Passport numbers, addresses, credit card details, your kid's birthday. The full internal booking object, served raw like gas station sushi.

Frontier's mobile app API has an endpoint that returns the entire raw internal booking object . The only authentication? A PNR and a last name. That's it. That's the security. Two pieces of information printed on every boarding pass in existence.

The response includes, for every passenger on the booking (including children):

The website masks passport numbers as XXXXX8151 . The API returns the full number. No filtering. No masking. The complete internal booking object, dumped straight to the client.

The KTN (Known Traveler Number) document. documentTypeCode "K". Full name, date of birth, gender. All in the API response.

The passport document. documentTypeCode "P". Full passport number (redacted), nationality "IT", issued by "IT", expiration date 2034. The website masks this. The API doesn't.

Your Known Traveler Number is what gives you TSA PreCheck. It's tied to your identity and lets you skip the long security line at US airports. If an attacker has your KTN, they can add it to their own booking and fraudulently gain PreCheck status, skipping enhanced security screening. You know, the screening that exists to stop bad things from happening on planes. TSA's own guidance says KTNs should be treated as sensitive and never exposed in client-side applications. Frontier dumps it in a JSON response to anyone with a 6-character code and a last name. Thanks Frontier, very cool.

Credit card details: accountNumber "XXXXXXXXXXXX7586" (last 4), expirationDate, BIN range, cardholder name, billing address including street/city/state/zip, billing email, billing IP address, authorization code, and payment amount ($609.88). All from one API call.

The binRange field in the JSON is the first 6 digits of the credit card number (the Bank Identification Number). Combined with the last 4 visible in accountNumber , that's 10 of 16 digits known. The 16th digit is deterministic (it's a Luhn check digit, calculated from the other 15). That leaves 5 unknown digits in the middle, which is ~100,000 possible combinations. That's not a theoretical attack, that's a for-loop.

Internal system logging every SMS and email notification sent to the passenger. "SMS Sent to [phone number]", "Email notify-gate-change sent to [email]@gmail.com". The API leaks info again through the notification logs even if you somehow missed it in the passenger data.

These are internal system logs. They re-expose the passenger's email and phone number in plaintext, embedded in notification text strings. Even if Frontier masked the fields (they don't), the would leak them anyway. It's like putting a privacy screen on your monitor but leaving the screen mirrored to a projector in the lobby.

In the booking I tested (from a publicly posted boarding pass on X), there was a 3-year-old child whose full name, date of birth, and gender were fully exposed.

The Manage My Booking page at flyfrontier.com displays your email address and phone number as masked. Great, right?

Except the full unmasked email is sitting right there in the HTML source. And it has been through two different versions of the code .

The old page had two leaks: window._mfq JavaScript variables and hidden elements. Both exposed the email.

window._mfq.push(["setVariable", "email", " [email protected] "]) alongside the PNR and last name.

[email protected] and xxxxx . Invisible on the page. Fully present in the source.

They removed both of those. Great, right? No. They replaced them with two new leaks that expose even more data. The old version only leaked your email. The new version also leaks your phone number.

window.NOIBUJS.addCustomAttribute('EmailAddress', ' [email protected] ') and addCustomAttribute('PhoneNumber', 'xxxxx') . Your email and phone number, in plaintext, in client-side JavaScript.

And the email also appears in a second place in the current page: an emailItinerary config object that includes currentEmail in plaintext:

"currentEmail":" [email protected] " sitting in a JavaScript config blob. Because one leak wasn't enough.

So to recap: the old page leaked your email in two places. They updated the code, removed those two leaks, and replaced them with two new leaks that also expose your phone number. They didn't fix the leak. They upgraded it.

I also found an endpoint that returned booking data for any valid PNR with no last name required :

Just a PNR. No last name. 200 OK. Full booking details, flight numbers, passenger names, seats, bags, miles. 4KB of data for a 6-character code.

PNRs are 6-character alphanumeric codes. They can be brute-forced. I confirmed this by pulling three separate bookings with PNRs that appeared to be incrementing. Three different passengers, three different bookings, zero authentication. This meant an attacker could enumerate bookings at scale with zero prior knowledge, harvest passenger names, then feed those into the mobile API for the full PII dump.

The complete attack chain requiring zero initial information:

This is the only vulnerability Frontier fixed. They closed the front door and left every window wide open. You just need a PNR + last name from a boarding pass photo instead of brute-forcing it. Progress!

The Passengers/Edit page in the Manage My Booking flow just... shows everything. No masking.

First name, last name, email, phone number, country, zip code. All pre-filled, all unmasked.

Date of birth, gender, Known Traveler Number. Right there in form fields.

Here's the thing that kills me: the page before this one masks the passport number as XXXXX8151 and hides the email. Then you click "Edit Passengers" and the page shows everything unmasked. Same booking. Same session. Same user. It's like locking the front door but leaving a sticky note on it that says "key is under the mat." If it's intentional masking, why does the edit page undo it? Did two different teams build these pages and never talk to each other? Is this a cry for help?

The server-rendered HTML also embeds a JSON blob containing:

The full passport number, nationality, issuing country, and expiration date. Just sitting in the HTML source of the page.

The KTN exposure is particularly bad. Per TSA handling guidance, Known Traveler Numbers should not be exposed to client-side rendered pages at all. An attacker with someone's KTN could fraudulently use it to gain TSA PreCheck status.

As explained above, with the BIN (first 6), last 4, and the Luhn check digit (deterministic), only 5 digits are unknown. ~100,000 combinations. That's not a theoretical attack. That's a for-loop that runs in seconds. Add the cardholder name, expiration date, and full billing address (which satisfies AVS for card-not-present transactions), and the only missing piece is the CVV.

Any PCI-DSS qualified assessor would rate this critical. At minimum, this is a reportable cardholder data exposure event to the acquirer under PCI-DSS 12.10.1.

They sent me a model plane though. So there's that.

As of June 16, 2026. Yes, really. I just checked again while writing this:

If you've ever flown Frontier and someone has your PNR and last name (from a boarding pass photo, a social media post, a discarded boarding pass, an airport trash can), your passport number, address, and payment details are accessible right now. If you traveled with children, their dates of birth and full names are exposed too.

I gave you 105 days. I set a 30-day deadline. You let it pass. You had more time than it takes to grow a tomato from seed.

You fixed the easiest vulnerability (the enumeration endpoint) and left the ones that actually leak passenger PII wide open. That's like fixing a broken window on a house that has no walls.

Your passengers deserve better. Their children deserve better.

After this post went live, a former Frontier Airlines employee reached out and provided the following statement:

"Reading through the code snippets provided, seeing IBE mentioned was a shock to my system, to say the least. Back when I worked there, IBE was already considered a legacy codebase which was delivered initially by their booking and logistics provider, who I won't name just in case. We were talking sunsetting it and replacing it with a cleaner, more modern solution. IBE was (and probably still is) a mess of generated config and code that only one person was senior enough to touch. Everyone else basically danced around it, myself included. By the time my contract was up, my then supervisor claimed to be in the process of rewriting the frontend again. Whether that actually happened or not, I can't say. This security incident does not surprise me in the slightest, knowing what the workplace culture was when I worked there, I can only imagine that it may have gotten worse."

I retested today. Most of it is actually fixed now. Credit where it's due:

Funny how that works. 105 days of responsible disclosure: tumbleweeds. One blog post and a little news coverage: fixed in a weekend. Glad to know the security team was capable of moving fast the whole time, they just needed the right motivation (public humiliation). Maybe instead of an email I should have just hired a skywriter to write in front of their HQ.

But one thing is still live, and it's the funniest one. The Manage My Booking page still embeds a window.wpromote analytics blob in client-side JavaScript containing the passenger's full Known Traveler Number (KTN) in plaintext, along with full passenger names, city, state, and zip:

Let me get this straight. Frontier went through and patched the mobile API, scrubbed the email leak, cleaned up the Passengers/Edit page... and somehow missed the TSA-sensitive Known Traveler Number sitting in a marketing analytics object on the same page. The variable is literally named tsaTravelNumber . It's not hiding. It's not obfuscated. It is using its government name. You could Ctrl+F for "tsa" and find it in three seconds. I'd say it's hiding in plain sight but it's not even hiding.

Per TSA handling guidance, KTNs should never appear in client-side rendered pages. An attacker with someone's KTN can fraudulently add it to their own booking to skip enhanced security screening. Which is presumably what the marketing team was thinking when they decided this needed to be in their analytics object. "We need to know which campaigns convert TSA PreCheck holders" is a sentence nobody has ever said, and yet, here we are.

So: meaningful progress on the worst of it. But the KTN is still leaking, just sitting in a wpromote object pretending it's a marketing metric. Fix this one too, Frontier. Or don't.

So long and thanks for all the fish.

Thanks for the model plane though. It's sitting ontop of my wardrobe. The wheels broke, just like your security. (The wings didnt fall off but I took one off for the blog header for added comedic effect.)

Extracted Entities

Attack Types (1)

Companies (2)

MITRE ATT&CK (1)