Hacker News new | comments | show | ask | jobs | submit login
Browser auto-fill phishing (github.com)
802 points by christop on Jan 5, 2017 | hide | past | web | favorite | 143 comments

Wow, great demonstration. I'd never thought about this being exploited. I wonder if the fix could be something as simple as the browser only allowing non-hidden [Edit: "not visible to the user", I should have said, as this does not appear to auto-fill <input type="hidden"> ] fields to be auto-filled. Otherwise, a warning about what auto-fill information (IE "Your name and credit card information are going to be submitted, continue?") has been filled in would be a nice touch. Maybe a browser extension could accomplish this?

The <input> elements are not hidden, they are just drawn off the screen. So the browser would have to determine if the item is visible to the user, which is not trivial. Should autofill skip regular form elements that are just a little below the viewport?

Maybe some feedback from the browser detailing which datapoints were autofilled. I don't know...

My thinking is the user should explicitly autofill each field. Yes, it involves more work, but it's really not much work to click on a field and pick the right autofill value.

I'm always concerned about using autofill because browsers eagerly fill any field they have data for.

This is how Firefox's autofill worked for me just now. Glad to see some more justification for getting off the Google train!

Firefox works that way and is in my view a much saner default. The best solution used to be in Opera long ago where they showed a little dropdown with the information that was going to be autofilled. You could accept it or deny it.

That sounds like a fantastic idea for an extention.

That would be super bad user experience. Simple and better alternative would be to show everything being auto filled in page in a browser dialog and confirm from user before actually auto filling it.

Another method would be to show a user a list of all fields that are about to be filled in as part of the autocomplete prompt. This isn't very scalable for massive forms, but should be enough of an alert to a user that something is amiss on screen to make up for those cases.

You can scale it by classifying fields into groups. Then user can decide gradually if he wants to share his name. Later, application may ask for location (browsers can already do this), employer info, contact data etc.

What is needed is integration with permission granting mechanisms, which already exist in browsers.

Actually this problem looks is a lot like how Android App permissions are managed. Not long ago some apps used to ask you at install time that they want access to your google email, contacts, wifi and so on. A better app permission model (which I think is now in android) is to ask these "lazily" as the app needs them and let the user decide at that point.

I like this best too. All it does is add one more click (when you select the auto fill info, it pops up with all the data and you just approve) and it also solves a lot of wrong fills that can happen.

There's often sites that are poorly coded, and autofills ends up putting my phone number in some random field and I have to manually delete it.

Safari does this already

In Safari, the autofill dropdown explicitly said it would fill "email, work, address" (and I guess it implies that name is included).

How obvious is this to the user? This seems like a detail that'd be easily overlooked.

It's quite obvious. Just tried it myself [1].

You first select an identity to use to auto-fill. When doing that, it will tell you the data it will insert in the subtitle.

You can also click customize and choose what data to place into each field.

[1] - http://imgur.com/a/HL59q

It's obvious in Safari but not so in Chrome

This is exactly how signing in to gmail works if the browser has the credentials of the account saved.

Initially only the input field for e-mail is displayed. There's also a, hidden to the user's eyes, _next step_ with the password field that gets populated if the browser auto-fills it.

> So the browser would have to determine if the item is visible to the user, which is not trivial

This is not terribly difficult, browsers need to know what is visible because they have to actually display it. If an element isn't drawn it shouldn't be autofilled.

> If an element isn't drawn it shouldn't be autofilled.

So if a form is too long and you need to scroll, all those fields you can't see won't be auto-filled? Sounds pretty terrible IMO.

To me (as a non autofill user), the published bug sounds way more harmful than a little inconvenience.

It's not just an inconvenience – it's broken and unexpected UI behaviour.

Well why not have it autofill on-draw?

It'd be easy to move the hidden elements on to the screen when the user clicks the submit button, so they'd be filled in and the form would then be submitted, and the information 'phished'.

The solution to this problem is to inform the user which fields will be completed by autofill, with a "not currently shown" highlight on any fields that are currently off the screen so the user understands what's happening.

Well, then simply make them height:0px or put a <div> with a white background over it. Change the input and make it text-color: white; background-color: white; Change it's z-index to be lower than your other elements, etc.

opacity: 0.01;

This makes the case that auto fill just ain't that secure, I guess if we use it we just need to accept that.

There's no need to "just accept" that it's not secure. We need to make it secure. This is a tedious/hard problem, yes. IMHO we've (people) solved tougher problems :)

  <div style="font-family: Custom non-printing font 101">
    <input type="text" name="address"/>
    <input type="text" name="ssn"/>

Adobe made a font like this, adobe blank: https://github.com/adobe-fonts/adobe-blank

Sure, but then the attacker can draw the fields within the 'visible' document, but below the 'fold'. If the browser chooses not to fill fields like that, it breaks a lot of autofill on long pages. Those two cases aren't significantly different.

Not necessarily. The browser often paints a much larger area than fits in the viewport, then hands it off to the GPU. (This can be cause performance issues for very tall scrollable pages, which is why I've run into it.)

What if another element is drawn in front of it, and though? I feel like there are a huge number of possible tricks to hide elements on page and trick the browser into thinking they're visible.

How many pixels does an input need to occupy before it's considered "visible"?

Problem is that a form might be longer or wider than the viewport, which would result in "hidden" elements in genuine browsers too.

> Should autofill skip regular form elements that are just a little below the viewport?

It's not trivial but if they do that, then we will be able to finally prevent the browser from autocompleting the fields incorrectly and end this bullsh1t: https://bugs.chromium.org/p/chromium/issues/detail?id=468153

>> which is not trivial

but is something the browser already does, so it's no extra effort.

I liked the old Opera approach to this. By default it did not fill the fields, unless you clicked on a Wand button, or used Ctrl+Enter shortcut.

This also worked really well with encrypted password storage (if you configured that key was forgotten after e.g. 10 minutes), it did not nag you to enter the password if you visited site where you stored password but did not intended to log in at given time.

There's an add-on for Firefox[1], but doesn't work as well as it did in Opera, and also it doesn't solve the password nagging issue, but I suppose it could help address the vulnerability mentioned here.

I really don't understand why all browsers insist to handle password this way.

[1] https://addons.mozilla.org/en-US/firefox/addon/secure-login/

I miss the magic wand so much. It also ignored autocomplete=false. Truly a tool that belonged to the user above all else.

Chrome doesn't fill in the fields by default either. The issue is what the autocomplete tool does after it has been activated, not how it's activated.

Also, while Opera's wand button filled in both login credentials and common form elements, Chrome's autocomplete is limited to common form elements.

Only allowing non-(display:none) fields wouldn't be enough. You could still position them off screen, or behind an image, or very small or nearly transparent, or any other sneaky tactic.

Your second idea about an auto-fill warning would be better. Maybe a simple footer warning or something.

I guess I did not think about offscreen or otherwise sneakily positioned form elements. I think the warning is the best way to handle this. I imagine it being something similar to an android permissions popup, where you can check off what should be "shared" (auto-filled) with the site before actually populating the form.

Then you'll love this concept: https://www.youtube.com/watch?v=3mk0RySeNsU A 1:18 "clickjacking" demo. (Link to video because I think this is legitimately one of those cases where a video can describe and demonstrate the problem faster than text.) You can google around for more info, or at least my YouTube is definitely popping up some other relevant videos.

Something like "Chrome has autofilled 12 fields" or something more userworldy would be good.

Or massive highlighting around each field

> Otherwise, a warning about what auto-fill information (IE "Your name and credit card information are going to be submitted, continue?")

FYI this doesn't work for credit card info, at least not in Chrome. That information has to be auto-filled separately.

It does "sort of" work on Chrome. It does give the end user a visual cue when typing in a name...the last 4 and the cc logo: http://i.imgur.com/2bY2Pes.png

But, if the end user doesn't notice or care about the visual cue, you can exploit it. Start typing in a name that has a credit card associated with it in Chrome's autofill: https://jsfiddle.net/hvs4ox2q/4/

Is it possible for JavaScript to trigger key presses on input boxes? Probably not.

If it was you could write a script to automatically post all auto fill data on page load.

Wow, this seems like such an obvious attack vector that I just assumed it was somehow mitigated (somewhere, magically, I suppose). Does it even require the user to press the Submit button, i.e. could the site's JS trigger the POST request after the event of the autofill?

No need for a submit click. Presumably auto-fill triggers a change event on each affected input, but even if it didn't, an attacker could just repeatedly check for new content in the inputs. This means an optimistic solution (autofilling and then unobtrusively notifying the user what was autofilled) is not viable.

I don't think it does trigger a change for exactly this reason. I tried to build a Material login page a couple years back, where the placeholder became the label when you typed. I couldn't get it to work with autofill, because I couldn't find a vector to detect when autofill had happened. Here's a related issue:


It doesn't trigger a change, but you can certainly poll for non empty strings: https://jsfiddle.net/k91o1dw9/7/

Edit: That is, for the purposes of this exploit. I understand it's ugly.

That's correct - this has also been a massive issue for React, and still isn't fixed in a released version. There's a fix that was merged some time ago, pending release with React 16 [1]. There's some discussion about a 3rd party effort to back-port to 15.x.

[1] https://github.com/facebook/react/issues/7211#issuecomment-2...)

Notice that it's not checking the data with JavaScript. I was under the impression that there is already a security measure against this as far as JavaScript is concerned. The browser is already instructed to lie to JavaScript about certain details such as the :visited state of a link and any CSS rules that follow as a result of this.

Even if you can't read the values with JavaScript, you can submit the form with JavaScript.

So then you'd need to prompt the users to confirm that they want to auto fill, not just notify that auto fill happened. Otherwise it may already be too late.

Even if you couldn't read any hidden value with JS and had no way of telling if they changed (didn't try it myself) you could submit the form every 5-10 seconds or so in the background and reject it server side if a hidden field is missing.

You can check the data with JavaScript if you poll. Try it out: https://jsfiddle.net/k91o1dw9/7/

Yup, you could AJAX-ily listen to the phish fields

This could be solved by improving the autofill UI to tell you all the data it is filling into the form, even if it isn't visible to you.

Currently, when I trigger autofill in Chrome, it tells me the full suite of information it can input for a certain profile (name, address, company, etc), but it doesn't tell me which bits of information are actually being used. Something as simple as placing checkmarks in this popup next to the information that is actually being used could communicate this better.

> This could be solved by improving the autofill UI to tell you all the data it is filling into the form, even if it isn't visible to you.

Safari does this already

In case anyone is worried, most (all?) browsers do not autofill credit card information without the user explicitly clicking into the credit card field so there's no chance of a hidden field stealing your CC information.

This requires the browser to recognize it as a credit card field.

Suppose a form uses a non-standard name for the field (say a localized name), and a user enters it at a legitimate site. Any attacker simply has to find these non-standard names for auto-complete to fill this in.

I feel like I've seen a credit card autofill before outside of normal controls.

But then the browser won't autofill it, so what's the problem?

It will if the attacker uses the same custom name for his field. The attacker could try to suck as much data as possible by creating thousands of hidden fields having a lot of possible combinations for the names of these non-standard CC fields, and wait to get lucky.

Why would I even care about credit card information being stolen. My bank will reimburse that no questions asked. I am much more concerned about my personal information being leaked. CC fraud costs other people money, identity fraud is much more damaging to me.

For many people living paycheck to paycheck, someone cleaning out their bank account would be quite harmful. Yes, the banks will reimburse them but that could take up to a week if not more. In the meantime when your rent and utility checks bounce, you could be in an extremely uncomfortable position.

And even when clicking into the credit card field you still need to click a little popup that asks if you want to autofill.... at least that's how it works for me, I don't remember ever changing a setting on Chrome for this so I assume this is the default state. In fact it does something similar for my address information too. There must be some setting because I know my address autofill info is saved in Chrome but when I tried the demo I did not see my address info in the headers

Last time I autofilled a CC with chrome it asked me to input the cvv number on the card before it filled in.

Interesting use of CVV, since vendors aren't permitted to store it. But Chrome does, for you... is that synced across browsers? That would require Google to store the CVV on its servers...

My understanding was that Google doesn't store your CVV anywhere, which is why you need to enter it every time. When you do so, it attempts to charge you zero units of your preferred currency (or perhaps it gives you zero, not sure) and if the transaction succeeds it accepts the CVV as valid.

Chrome isn't a credit card vendor. I can save your credit card number for you too, if you want.

The CCV check Chrome does doesn't compare the entered CCV against anything stored at all. Instead, it charges a small amount to verify the credit card. See my comment below.

Your mileage my vary, but I'd be very surprised if it does.

Chrome doesn't store the CVV, Google does. It syncs with your Google wallet account, and if the CVV is matched, then the credit card is auto filled

This is what happens to me:

1) Google Chrome doesn't always explicitly ask for a CCV. If it does, the browser dialog opens.

2) It actually charges $1 per CCV check to verify the credit card.

3) If the CCV check is successful, it does the autofill on the form. However, you still have to enter the CCV in the form manually most of the time.

4) The $1 charge is immediately canceled and thus doesn't affect your account balance.

For reference, here's a screenshot of how my bank receives such a charge: http://imgur.com/qwdM9Jx.png

To be clear, this is not from any Google purchase. That's what happens if I use my CC in Chrome on any site.

It also has to be noted that this implementation is pretty bad. On pre-paid CC (i.e. your CC payments are directly tied to your bank account - there is no CC bill), this will negatively impact your spending balance:

Account balance: All your money.

Spending balance: (account balance) - (pending charges)

Some banks refuse to apply the charge cancellation sent by Google and keep the pending charge active for some fixed amount of time (e.g. 90 days).

I don't know about this feature, but why couldn't it be stored as a hash?

I might be an order of magnitude off here, but I believe there's only around 1 billion unique numbers per card once you take away check sum digits and look at how they are issued.

Assuming that's correct, it really wouldn't take up much memory or computing power to create a lookup table for every credit card number with hash x.

Chrome does autofill CC info based on just a name if you want. It does give the user a visual cue as to what might happen http://i.imgur.com/2bY2Pes.png

You might catch some careless people with it though: https://jsfiddle.net/hvs4ox2q/4/

And Jeremiah Grossman was talking about it a decade ago. It's amazing these problems persist.

haha, I guess I also reinvented the wheel a few months later :)


Also, malicious scripts can change the password input type field to a regular text field and grab it from there.

There's no need to convert the input type to get the plain text value of a password input. It just masks the input value visually.

Firefox doesn't exhibit this behavior, but the site doesn't specifically state which browsers this affects.

Indeed, I'm really glad there is at least one popular browser not affected by this.

This is one of the many examples where a privacy-first approach pays off not just in terms of privacy but also in terms of security. In Germany we use the term "Datensparsamkeit" for this principle. Not sure if there is a well-established english term in the international community.

So why do other browers fill in these fields automatically? Why don't they wait until asked by the user? Because it is more "convenient" for the user? Moreover who benefits from that? Not the users, not the browser vendors, but all those websites with overly long registration forms. These confront their visitors with lots of irrelevant fields (birthday, gender, etc.) just for the sake of collecting data. Nobody would fill all that in voluntarily, but I guess more people will do so (perhaps accidentally) if their browser fills that in by default.

Firefox is secure against this. FF needs you to right click an input field and select an identity to use for autofill.

But Safari does it in the most elegant way. They show a popup with all the information that will be autofilled and ask you to confirm before filling out the fields which also protects against AJAXified submissions.

I found this https://bugs.chromium.org/p/chromium/issues/detail?id=132135 which was created when someone noticed the issue happening to their honeypot input box. Looks like it was closed a while ago.

I saw this example doing the rounds on twitter. Hopefully the chrome devs notice the noise and move up the priority on fixing / addressing it.

> Chrome Autofill is specifically designed to help users quickly fill forms that they've never filled before.

Browsers auto-guessing private data into arbitrary fields on never-before-used webpages?

IMO that's "Just because you can doesn't mean you should" territory.

This is why I never put anything secret into browser autofill data. No credit cards, no passwords, nothing I would not be OK with disclosing publicly, or already did.

Sensitive info belongs to a password manager which limits it to the domains the data belong.

Credit card numbers are a pain, though. I could put them to a password manager, and manually select to fill only that particular field when I need to. In reality I rarely buy things where PayPal or Amazon payment options are not available; I suppose Stripe offers a similar service.

> Sensitive info belongs to a password manager which limits it to the domains the data belong.

So all that stands between you and being in this exact situation (or worse, since passwords) is your password manager's url comparison?

I refuse to use LastPass - the interface is horrible (probably because you're expected to use the browser extension). But I don't want my password manager anywhere near my browser. I'd really rather have to take an affirmative action in order to release each individual piece of information so I know what I'm disclosing and to who.

    your password manager's url comparison?
Better than manual url comparision! A surprising number of humans think things like www.goodcompany.evil.com are urls for "Good Company", and anyone can screw up and make mistakes checking urls (www.goodcomany.com).

Add Unicode and it gets worse. I don't trust my eyes to differentiate between Cyrillic а and Latin a. https://en.wikipedia.org/wiki/IDN_homograph_attack

Browsers only display unicode in domain names if the TLD has restrictions on character sets that prevent homograph attacks.

See https://en.wikipedia.org/wiki/IDN_homograph_attack#Defending...

Well, yes. A domain name, when backed by an SSL certificate, gives a modicum of certainty that information is not being siphoned to a third party.

A password manager running outside my browser and only communicating the bare minimum required by a page, after checking its certificate, sound like a good idea. LastPass is almost there; the only reservation is that it's not run on a machine controlled by you. Other similar solutions overcome this limitation.

A browser extension is actually a great approach, too: it can and should be open-source and signed, thus reasonably tamper-proof. It should, again, do the bare minimum regarding the communication with the actual password store. Its usefulness is mostly in discovering the mapping between form controls and info to be stored.

Browsers don't auto-fill credit cards and passwords, today, because they are private.

Chrome (and I assume others) has a secure credit card and password auto-fill, separate from regular form auto-fill.

This vulnerability was published (another article) over a year ago. I'm surprised Chrome hasn't fixed it.

I think this means browsers will never fix this issue. I won't be using auto-fill on untrusted webaites.

This is a very old exploit. The earliest references I could find were from 2010.

As other comments have noted, it isn't trivial to fix completely, so I believe most browsers just haven't bothered at all, but have implemented some extra protection for credit cards (and of course, CVV numbers are never stored in the first place).

Not all browsers - Firefox suggests form input values one by one (when you click in the field) so it is not vulnerable AFAICT.

I'd rather have only the field I selected autofilled and be given a secondary option to have every field (or maybe choose which fields) in a form autofilled. This bothers me in innocent, non-phishing forms too—especially when the designers don't put labels on the fields and only use placeholders, which I can no longer see after autofill.

Safari lets you choose which fields to fill in by clicking a "Customize" option that pops up, but I doubt any normal user will bother looking that far.

Even as an experienced user it never crossed my mind that this might happen. Good catch

LastPass prompts every time before autofilling your CC# into a form, so it might avoid this issue in that case.

I do believe it would still fail exposing your basic info, such as in this example, however.

Basic info is more critical than credit card numbers, at least in my country (Australia) where the issuer or merchant would be liable for any subsequent fraudulent transactions; at worst I would be inconvenienced a few days whilst a new card & number was issued. Compared to outright identity theft, that's minor.

LastPass has previously had autofill exploits (not with regards to CC though). I would highly recommend disabling auto-fill.

Yes! I always had this itch whenever I filled out a field and had the other fields pre filled by chrome. I actually thought that maybe there were type="hidden" that could have been filled and sent (although as someone points out those aren't but it isn't hard to hide an input with CSS). But the main point is: whenever I did that I was usually OK with sending out the rest of the information which either was outdated or I was consciously aware of it.

However, a lot of users might not have that conscience and might be giving out information which they didn't want to. It would be great to shame websites that were employing these shady techniques, but the solution must come from Chrome. Chrome devs: by default only auto fill one field and on the drop down have as the last option to do what you do now, so that you're sure that the user has consciously chosen to auto fill all fields * have a little disclaimer saying this possibility *. That way you get the best of both worlds with an extra key down

PS: and/or like someone said that happens in Safari: name the fields that you are about to autofill in the last choice to autofill everything

If I remember correctly, it has been reported several times in the past and Chrome doesn't care about it at all.

Fillr autofill app requires users to approve every piece of data before autofilling a form. Makes it easy to know when a site is trying something shifty. Dashlane also lets you pick exactly what to fill. Native browser autofills have been battling phishing exploits since early IE days.

I really with that browsers didn't autocomplete ever. I've had instances where they will happily auto-complete my entire credit card number. Usually, they'll only memorize the first 4 digits, but sometimes they memorize the entire thing.

For me it pops up a little box under the input asking me to choose if I want to autofill. I like this option because it doesn't autofill without permission but my info is still saved and easily accessible.

autofill actually annoys me, which is why it's one of the first things i disable when setting up my browser(s)

Complete tangent but... why is this a NPM package? There is no actual Javascript code in it.

It's not actually published on npmjs.org. Author probably just ran npm init out of force of habit. It's actually quite nice that they have their standard metadata & licence where it's easy to find.

They should probably have private: true in there though, to stop it getting published by mistake, since it isn't a component anyone could usefully import.

Just confirmed 1Password’s AutoFill for identity is also vulnerable to this on Chrome.

Was this filed against Firefox, Chrome, and EDGE? (it seems like the kind of PoC that you make to prove a point to browser vendors to get them to fix what should obvioulsy be fixed... if the user can't see it, no matter how that's been achieved, don't autofill that field.)

Firefox is not vulnerable.

Chrome was shown to be vulnerable like 7 years ago but nothing changed.

Closed source stuff like MSIE or Safari? No idea, ask a Windows os OS X user.

MS EDGE, unlike the now hopelessly outdated Internet Explorer, has an open issue tracker. And as Safari is literally just webkit, which also has an open issue tracker, there was no need to pretend to be better than Windows and OSX users by pretending they're on their own.

And Chrome wants to ignore autocomplete=off (https://news.ycombinator.com/item?id=11911116)

Why not? Anyone who wants to steal your information would not try to disable autocomplete anyway.

You're right, following standard in regard to autocomplete=off will not prevent this attack.

I think I remembered of that because the direction of though that autocomplete should always be enabled appears as wrong to me. And this situation reminded me of this direction of though in the past case.

This is the reason I never use the autofill beyond more than at typechecker. I still explicitly write out what I want to place in the form, and the autofill helps me avoid typos.

However, I always found it odd how something so prone to this kind of attack could be deployed for all non-tech savvy browser users...

I actually ran across this a while ago, but didn't think to call it phishing.

I was trying to create a honeypot for a front-facing web form, but because of the name I gave the honeypot field, some people's autofill information was filling out that field without them knowing.

This is a very clever hack. I've tried in the past to adjust my HTML to disable autofill and it's not possible to prevent Chrome from aggressively doing it.

It's disabled if you do autocomplete=off in the attributes

Not in my tests, it continued to aggressively populate forms with autocomplete="off" set.

That would be because that attribute is for a different feature of the browser. The autofill that this method takes advantage of is more of an extension beyond the standard browser feature.

Besides, someone using this for a phishing method wouldn't use that attribute anyway.

The only thing I can think of is a separate prompt, that would ask "Do you want to autofill Name, Address, Phone..." etc.

That popup is not needed. Firefox does this simply through auto-complete. The user starts typing their email address, and voila, the browser completes it.

This is a nice example of a feature that is trivially accessible and yet unobtrusive.

(Alternatively, you can press the down-arrow on the empty field, which will open the auto-completion as well.)

Old Opera went one step further, where it would fill forms using a Wand button. This approach also was used for logging in.

IMO, much better way, since it works well in situation where your passwords are encrypted and browser is configured to forget master key after a while.

Firefox in that scenario will bug you about master password each time you go to page where such password is stored.

That's what Safari actually does

It even works in incognito mode (Chrome 55.0.2883.87 on Windows 8.1; tested against my bank's website).

Saw the title of this, didn't even open the link, just thought "oh... Crap."

Save forms data and especially save passwords have always seemed phishy to me.

Yet more blowback from trying to be "user friendly"...

Didn't work for me. Chrome 55.0.2883.87

are there are api products or chrome-plugins to check / verify if a certain page is a phishing-attack ?

I get 405 after submit.

me too, but just use the developer console to see the same (horrifying) results as shown in the gif.


ok, let's try.

ok lets try..

Great state of the web

It's not the web as it's working as it should, this is a browser problem.

Applications are open for YC Winter 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact