Criticizing United's flagrant disregard for information security best practices

Criticizing United's flagrant disregard for information security best practices

When I recently called United Airlines customer service, they asked me for the first five characters of my password as verification!

If this doesn't strike you as odd, I will explain why this is a security failure from both a user experience standpoint and a technical standpoint, and why it bodes poorly for United's competence as a steward of your data.

In case you're already balking at this lapse in security, yes, it was really United. As I publish this post, I can confirm that when calling 1-800-UNITED-1 from a number that is associated with a MileagePlus account, you will still be verbally prompted for part of your password (ask for "MileagePlus" → "My Account" → "Other Questions").

Much like users are trained not to click on links sent in emails, they should be suspicious when asked for a password. End users shouldn't be asked for password information over the phone. While users can check whether or not a website is secure (https-enabled, certificate valid), a phone call does not lend itself to validation from the user's end. Dialing phone numbers can be an error-prone process. Training United customers to expect that they might be verbally asked for their password is a security failure.

Setting aside the user experience implications of this security failure, the technical implications are even more concerning. To explain, let's go over the basics of backend password management.

This post is not a tutorial. I intentionally omit details (difference hashing functions, KDF's, etc.) that should be understood when implementing backend password management but are not necessary to understand this security failure.

Consider the following authentication databases for a service with users Jane and John, who happen to have the same password, P@ssw0rd.

user password
Jane P@ssw0rd
John P@ssw0rd

If attackers compromised the database above, they could directly authenticate as Jane or John using the passwords stored in plain-text. For this reason, we use password hashes. By applying a hashing function to an input password, an irreversible transformation occurs. The output hash is stored in the database (see below). When a user authenticates, their input password is run through the same hashing function, and the output is validated against the stored hash. Because "b03d..." does not hash to itself, an attacker could not directly authenticate as Jane or John using a compromised database[1].

user hash(password)
Jane b03ddf3ca2e714a6548e7495e2a03f5e824eaac9837cd7f159c67b90fb4b7342
John b03ddf3ca2e714a6548e7495e2a03f5e824eaac9837cd7f159c67b90fb4b7342

Hashing doesn't fully mitigate the dangers of a compromised database. An attacker could generate hashes for many different passwords and reverse-lookup the password from the hash, then using the password to authenticate as Jane or John. Above, Jane and John's passwords hashed to the same value, one that attackers would already have in their reverse lookup table.

Enter salting. Combining user passwords with a user-specific random value, called a salt, before hashing, results in Jane and John having different hashes for the same password. Likewise, attackers with a pre-computed reverse-lookup table would have a different hash and be unable to reverse lookup the hash without generating a reverse lookup table for each user/salt, which is much more time consuming.

user hash(password + salt) salt
Jane 13574f0c00712f2aced4a04f8b39285ca9370ba4649d34e4d70... random A
John e657fc48af48826e111704c62c0a549af159208e86616243253... random B

For United to be able to validate the first five characters of your password separately from the whole password, their database must look something like this:

user hash(first five characters + salt) hash(full password + salt) salt
Jane 5fc873af8eed813b988d... 13574f0c00712f2aced4... random A
John bfae5c257f38e1d7c96e... e657fc48af48826e1117... random B

Because United can validate the first five characters of your password, in the event of a database compromise, attackers could as well, cracking the second half separately.

If a properly implemented password database is a 4-digit combination lock (10,000 possible combinations), United is protecting your account with two 2-digit combination locks (200 possible combinations).

Not to mention that dictionary or phrase-based passwords are common, and by learning the first 5 characters, attackers could narrow down the search space for the rest of the password. By cracking John's first five characters, I would intuit from P@ssw that his password is some representation of the word "password."

It is worth pointing out that I am critiquing the best-case scenario given United's ability to validate the first five characters of your password. Hopefully, United is following other best practices, such as using modern key derivation functions (KDF's such as argon2 or bcrypt). Nevertheless, even if United employs intensive key stretching on both the first five characters and full password, the factor by which this bad practice degrades password complexity is the same. For an engineer to implement this database schema, they clearly did not understand these concepts that are fundamental to backend password management, which gives pause for concern that United's bad practices are more pervasive than we already know.

United's Attitude Problem

Searching for a point-of-contact where I could bring attention to this bad practice, I found and emailed United Airline's bug bounty program, hoping to catch the ear of a competent security engineer. As expected, United does not consider my finding to be a bug. Having specifically pointed out that my finding was "not a bug" in my email to United, I agree. Nevertheless, bug bounty programs should consider making evidence of security anti-patterns "in-scope." From my conversation with United, it was never evident that there is a path towards fixing the issue, which would not be the case if bad practices were treated like bugs.

I later learned that by emailing United, I may have implicitly agreed to the "Terms of Service" outlined in a collapsed field below the bug bounty contact email. One clause of the terms: "Bugs or potential Bugs you discover may not at any time be disclosed publicly or to a third-party. Doing so will disqualify you from receiving award miles." Despite the fact that my email never outlined a potential bug, United confirmed that I would disqualify myself from future participation in their bug bounty program by publishing this post.

Suffice it to say that I am no fan of United. At this point, I have called United's customer service only to be unpleasantly surprised at the password verification, and I've notified United's security team only to be unpleasantly surprised by the way they present terms of service.

Then, there's United's position on security, highlighted on the bug bounty program's front page:

We utilize best practices and are confident that our systems are secure.

Compromises happen because bugs are real, which is why standards exist to mitigate the consequences of inevitable attack. United's disregard for best practice reflects the irresponsible attitude that their "systems are secure" – a particularly disappointing stance from a bug bounty program.


1. pass-the-hash (PtH) attacks do exist, but are not intristic to hashed passwords; rather, they are the result of some bad authentication implementation