Disabling Safari autofill on usernames and passwords

HtmlSecurityAutocompleteSafariAutofill

Html Problem Overview


You might already know, that Safari has a nasty autofill bug where it fills email, username and password fields no matter if you set autocomplete="off" or not.

Here's a basic form:

<form action="/" method="post">
    <p>
        <label>E-mail</label>
        <input type="text" name="email" value="" />
    </p>
    <p>
        <label>Password</label>
        <input type="password" name="password" value="" />
    </p>
</form>

...Safari autofills those fields on page load like it should, job well done!

If you put autocomplete="off" to the fields and/or the form element, Safari still autofills those fields:

<form action="/" method="post" autocomplete="off">
    <p>
        <label>E-mail</label>
        <input type="text" name="email" value="" autocomplete="off" />
    </p>
    <p>
        <label>Password</label>
        <input type="password" name="password" value="" autocomplete="off" />
    </p>
</form>

Even this doesn't work:

<form action="/" method="post" autocomplete="off">
    <p>
        <label>E-mail</label>
        <input type="text" name="secretfield1" value="" autocomplete="off"/>
    </p>
    <p>
        <label>Password</label>
        <input type="password" name="secretfield2" value="" autocomplete="off" />
    </p>
</form>

...since Safari looks up those <label> elements if they contain words "E-mail", "Password" etc. and goes ahead with the autofill.

Aaaahhhhha!, I thought, and tried this:

<form action="/" method="post" autocomplete="off">
    <p>
        <label>%REPLACE_EMAIL_TITLE%</label>
        <input type="text" name="%REPLACE_EMAIL_NAME%" value="" autocomplete="off"/>
    </p>
    <p>
        <label>%REPLACE_PASSWORD_TITLE%</label>
        <input type="password" name="%REPLACE_PASSWORD_NAME%" value="" autocomplete="off" />
    </p>
</form>

...and replace %TAGS% with the real names using JavaScript. Safari autofill kicks in. No matter if you set a 10 second timeout on the replacement.

So, is this really the only option?

<form action="/" method="post" autocomplete="off">
    <p>
        <label>That electronic postal address we all use, but can't write the title here because Safari fills this with YOUR information if you have autofill turned on</label>
        <input type="text" name="someelectronicpostaladdress" value="" autocomplete="off"/>
    </p>
    <p>
        <label>A set of characters, letters, numbers and special characters that is so secret that only you or the user you are changing it for knows, but can't write the title here because Safari sucks</label>
        <input type="password" name="setofseeecretcharacters" value="" autocomplete="off" />
    </p>
</form>

I hope not?

UPDATE: @skithund pointed out in Twitter, that Safari is getting a 4.0.3 update, which mentions "Login AutoFill". Does anyone know if that update is going to fix this?

Html Solutions


Solution 1 - Html

The reason browsers are ignoring autocomplete=off is because there have been some web-sites that tried to disable auto-completing of passwords.

That is wrong.

And in July 2014 Firefox was the last major browser to finally implement the change to ignore any web-site that tries to turn off autocompleting of passwords.

> One of the top user-complaints about our HTML Forms AutoComplete feature is “It doesn’t work– I don’t see any of my previously entered text.” When debugging such cases, we usually find that the site has explicitly disabled the feature using the provided attribute, but of course, users have no idea that the site has done so and simply assume that IE is buggy. In my experience, when features are hidden or replaced, users will usually blame the browser, not the website.

Any attempt by any web-site to circumvent the browser's preference is wrong, that is why browsers ignore it. There is no reason known why a web-site should try to disable saving of passwords.

  • Chrome ignores it
  • Safari ignores it
  • IE ignores it
  • Firefox ignores it

> At this point, web developers typically protest “But I wouldn’t do this everywhere– only in a few little bits where it makes sense!” Even if that’s true, unfortunately, this is yet another case where there’s really no way for the browser to tell the difference. Remember, popup windows were once a happy, useful part of the web browsing experience, until their abuse by advertisers made them the bane of users everywhere. Inevitably, all browsers began blocking popups, breaking even the “good” sites that used popups with good taste and discretion.

What if I'm a special snowflake?

There are people who bring up a good use-case:

> I have a shared, public area, kiosk style computer. We don't want someone to (accidentally or intentionally) save their password so the next user could use it.

That does not violate the statement:

> Any attempt by any web-site to circumvent the browser's preference is wrong

That is because in the case of a shared kiosk:

  • it is not the web-server that has the oddball policy
  • it is the client user-agent that has the oddball policy

The browser (the shared computer) is the one that has the requirement that it not try to save passwords.

The correct way to prevent the browser from saving passwords
is to configure the browser to not save passwords.

Since you have locked down and control this kiosk computer: you control the settings. That includes the option of saving passwords.

In Chrome and Internet Explorer, you configure those options using Group Policies (e.g. registry keys).

From the Chrome Policy List:

> AutoFillEnabled > ----------- > > Enable AutoFill > > Data type: Boolean (REG_DWORD) > > Windows registry location: Software\Policies\Chromium\AutoFillEnabled > > Description: Enables Chromium's AutoFill feature and allows users to auto complete web forms using previously stored information such as address or credit card information. If you disable this setting, AutoFill will be inaccessible to users. If you enable this setting or do not set a value, AutoFill will remain under the control of the user. This will allow them to configure AutoFill profiles and to switch AutoFill on or off at their own discretion.

Please pass the word up to corporate managers that trying to disable autocompleting of password is wrong. It is so wrong that browsers are intentionally ignoring anyone who tries to do it. Those people should stop doing the wrong thing.™

Put it another way

In other words:

  • if the users browser
  • mistakes "Please enter the name of your favorite maiden name's first color." for a new password
  • and the user
  • doesn't want their browser
  • to update their password,
  • then they
  • will click Nope

enter image description here

  • if i want to save my HIPPA password: that's my right
  • if i want to save my PCI password: that's my right
  • if i want to save the "new password for the user": that's my right
  • if i want to save the one-time-password: that's my right
  • if i want to save my "first color's favorite maiden" answer: that's my right.

It's not your job to over-rule the user's wishes. It's their browser; not yours.

Solution 2 - Html

I had the same problem. And though my solution is not perfect, it seems to work. Basically, Safari seems to look for an input field with password and username and always tries to fill it. So, my solution was to add a fake username and password field before the current one which Safari could fill. I tried using style="display: none;" but that did not work. So, eventually, I just used style="position:absolute; top:-50px;" and this hid the input field out of sight and seemed to work fine. I did not want to use JavaScript but I guess you could hide it with JavaScript.

Now Safari never autocompleted my username and password fields.

Solution 3 - Html

Fix: browser autofill in by readonly-mode and set writable on focus

 <input type="password" readonly onfocus="this.removeAttribute('readonly');"/>

(focus = at mouse click and tabbing through fields)

Update: Mobile Safari sets cursor in the field, but does not show virtual keyboard. New Fix works like before but handles virtual keyboard:

<input id="email" readonly type="email" onfocus="if (this.hasAttribute('readonly')) {
    this.removeAttribute('readonly');
    // fix for mobile safari to show virtual keyboard
    this.blur();    this.focus();  }" />

Live Demo https://jsfiddle.net/danielsuess/n0scguv6/

// UpdateEnd

Explanation: Browser auto fills credentials to wrong text field?

Ok, you just noticed that: > Safari autofill kicks in. No matter [what the fields are named] @Jari

and there's an assumption that: > Safari seems to look for an input field with password and username and always tries to fill it @user3172174

Sometimes I notice this strange behavior on Chrome and Safari, when there are password fields in the same form. I guess, the browser looks for a password field to insert your saved credentials. Then it autofills username into the nearest textlike-input field , that appears prior the password field in DOM (just guessing due to observation). As the browser is the last instance and you can not control it,

sometimes even autocomplete=off would not prevent to fill in credentials into wrong fields, but not user or nickname field.

This readonly-fix above worked for me.

Solution 4 - Html

Adding the CSS to the input will hide the Safari button pseudo-element and users will not be able to use autocomplete:

input::-webkit-contacts-auto-fill-button, 
input::-webkit-credentials-auto-fill-button {
  visibility: hidden;
  position: absolute;
  right: 0;
}

Solution 5 - Html

After scanning through Apple's Safari HTML pages and not finding anything on auto complete, I did some searching and thinking.

After reading a (mildly) related question on Apple discussions, I remembered that the default is to not allow remembered passwords, etc (which can be enabled in iDevice system settings, or at the prompt). Since Apple has moved this feature out of the browser and into their (proprietary, i)OS (screen shots on this article), I believe they are ignoring the HTML form/field property entirely.

Unless they change their mentality as to this feature, as I'm sure this is their expected behavior, on their locked down devices, I would work under the assumption that this isn't going away. This is probably different for native iOS apps. Definitely keep the form autocomplete="off" and hopefully they'll one day get back to the HTML5 standard for the feature.

I know this doesn't include any work around, but I think if you come to terms with it being a non-browser 'feature' on iDevices, it makes sense (in an Apple kind of way).

Solution 6 - Html

This question has already been successfully answered, but as of today's date, the solution didn't work for me without making some oddly particular changes - so I'm noting it here as much for my own reference if I decide to come back to it as for everyone else's.

  • The fake input needs to be after the real email input in the dom.
  • The fake input requires a fake label.
  • The fake label cannot be absolutely positioned.
  • Can't use display, visibility or opacity to hide the fake elements.

The only solution I found was to clip the visibility of the fake elements with overflow: hidden.

<label for="user_email">Email</label>
<input autocomplete="off" type="text" value="[email protected]" name="user[email]" id="user_email">
<!-- Safari looks for email inputs and overwrites the existing value with the user's personal email. This hack catches the autofill in a hidden input. -->
<label for="fake_email" aria-hidden="true" style="height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px)">Email</label>
<input type="text" name="fake[email]" id="fake_email" style="height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px)" tab-index="-1" aria-hidden="true">

For the record, the particular case this hack came in useful for was one where an admin is editing the profile of other users and Safari was replacing the email of the user with the email of the admin. We've decided that for the small (but frustrating) amount of support requests that this Safari 'feature' creates, it's not worth maintaining a hack that seems to need to evolve as Safari tightens up on it, and instead provide support to those users on how to turn off autofill.

Solution 7 - Html

I can't believe this is still an issue so long after it's been reported. The above solutions didn't work for me, as safari seemed to know when the element was not displayed or off-screen, however the following did work for me:

<div style="position:absolute;height:0px; overflow:hidden; ">
  Username <input type="text" name="fake_safari_username" >
  Password <input type="password" name="fake_safari_password">
</div>

Hope that's useful for somebody!

Solution 8 - Html

I have also been bitten by Safari's weird default autocomplete behaviour, but rather than completely disable it, I managed to make it work for me by following the guidelines at https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands.

Specifically, I put autocomplete="username" on the username field and autocomplete="password-current" on the password field. This tells the browser which fields to autofill, rather than having it guess, and it fixed autocomplete for my use case.

This approach works for both "email first" login forms (password field not immediately visible, eg Google login) as well as conventional login forms with both username and password fields visible.

Solution 9 - Html

Just put search into the name, Safari will ignore the field for autofill.

<input type="password" name="notsearch_password">

Solution 10 - Html

My issue: I have a section in an admin area that allows users to set all language values, some of which contain the words "password", "email", "email address" etc. I don't want these values to be filled with the user's details, they are for creating translations into another language. This is then a valid exception to the "circumvent the browser's preference" mentioned.

My solution: I simply created alternate names:

$name = str_replace('email','em___l',$name);
$name = str_replace('password','pa___d',$name);

<input type="text" name="<?=$name?>" id="<?=$name?>" />

Then when the form is posted:

foreach($_POST as $name=>$value) {
    $name=str_replace('em___l','email',$name);
    $name=str_replace('pa___d','password',$name);
    $_POST[$name]=$value;
}

This is the only method that worked for me.

Solution 11 - Html

You can try this variant. It works for me. If you change field value once, Safari will change it again. If user clicked at this field, after this the value wouldn't be changed by Safari automatically.

  $.browser.chrome = /chrome/.test(navigator.userAgent.toLowerCase());
        if($.browser.chrome){
            $.browser.safari = false;
        }

        var isChanged=false;

        $('#Email').change(function () {
            if ($.browser.safari && !isChanged) {
                $('#Email').val('@Model.Email');
            }
        });

        $('#Email').click(function () {
            if ( $.browser.safari && !isChanged) {
                isChanged = true;
            }
        }); var isChangePassword = false;
    $('#OldPassword').change(function () {
        if ($.browser.safari && !isChangePassword) {
            $('#OldPassword').val('');
        }
    });

    $('#OldPassword').click(function () {
        if ($.browser.safari && !isChangePassword) {
            isChangePassword= true;
        }
    });

Solution 12 - Html

Better than use JS to clear content - simply fake password field:

<input type="text" name="user" />
<input fake_pass type="password" style="display:none"/>
<input type="password" name="pass" />

A password type doubled put the browser in incertitude so it autocompletes only user name

fake_pass input should not have name attribute to keep $_POST clean!

Solution 13 - Html

It seems the browser programmers think they know more than the website writers. While it's sometimes handy to allow the user to save passwords, there are other times when it's a security risk. For those times, this workaround might help:

Start by using a conventional text input, instead of a 'password' type.

Password: &nbsp <input type="text" id="fkpass" name="bxpass" class="tinp" size="20" />

Then - if you wish - set the focus to the input field.

<BODY onLoad="fitform()">

Put the JS at the end of the page.

<script type="text/javascript">
document.entry.fkpass.focus();
function fitform() {
document.getElementById('fkpass').autocomplete = 'off';
}
</script>

Now you have a conventional form field. What good is that?
Change the CSS style for that input so it uses a font that is all 'bullets' instead of characters.

<style type="text/css">
@font-face { font-family: fdot; src: url('images/dot5.ttf'); }
@font-face { font-family: idot; src: url('images/dot5.eot'); }
@font-face { font-family: wdot; src: url('images/dot5.woff'); }
@font-face { font-family: w2dot; src: url('images/dot5.woff2'); }
.tinp { font-family: fdot, idot, wdot, w2dot; color: #000; font-size:18px; }
</style>

Yes, you could 'tidy up' the code, and add .svg to it.

Either way, the end result is indistinguishable from the 'real' password input, and the browser won't offer to save it.

If you want the font, it's http://www.millard.info/dot_webfont_kit.zip">here</a>;. It was created with CorelDraw and converted with an online webfont conversion utility. (dot_webfont_kit.zip 19.3k)

I hope this helps.

Solution 14 - Html

Remove <form> element. To keep form behavior you can listen keypress event for input fields to handle enter key pressed. Just in case I removed input type="submit" too. You can use button type="button".

Solution 15 - Html

The CSS display: none solutions mentioned here did not work for me (October 2016). I fixed this issue with JavaScript.

I don't mind the browser remembering passwords, but wanted to prevent a bad autofill. In my case, a form with a password field and no associated username field. (User edit form in Drupal 7 site, where the password field is required only for some operations.) Whatever I tried, Safari would find a victim field for the username of the autofilled password (the field placed visually before, for instance).

I'm restoring the original value as soon as Safari does the autofill. I'm trying this only for the first 2 seconds after page load. Probably even lower value is OK. My tests showed the autofill happens around 250 ms after page load (though I imagine this number depends a lot on how the page is constructed and loaded).

Here's my JavaScript code (with jQuery):

// Workaround for Safari autofill of the e-mail field with the username.
// Try every 50ms during 2s to reset the e-mail to its original value.
// Prevent this reset if user might have changed the e-mail himself, by
// detecting focus on the field.
if ($('#edit-mail').length) {
  var element = $('#edit-mail');
  var original = element.attr('value');
  var interval = setInterval(function() {
    if ($(document.activeElement).is(element)) {
      stop();
    } else if (element.val() != original) {
      element.val(original);
      stop();
    }
  }, 50);
  var stop = function() {
    clearTimeout(timeout);
    clearInterval(interval);
  }
  var timeout = setTimeout(function() {
    clearInterval(interval);
  }, 2000);
}

Solution 16 - Html

I had the same problem suddenly in a SPA with React in Mobile Safari 10.3.1

I do not need any tricky workarounds before in all tested browsers, even Mobile Safari IOS 10.2

But since 10.3.1 username or password will be filled in fields mentioning the words 'password','email','username' in any forms after login with active remember option. It seems that the rendered DOM-Tree is 'analyzed' using a full text search and then the user agent fill in data without respecting any autocomplete="off" setting. Happens funnyli also on placeholder text for a field. So you must be very carful with naming, when you don't want to have prefilled username or password in places where this data is not useful.

The only solution after hours of investigating was the solution here posted too. Provide a input field named "email" and hideout the containing div with height: 0px, overflow: hidden.

Solution 17 - Html

You can disable it by adding this attribute to password input

autocomplete="new-password"

Solution 18 - Html

For me, this problem was very sharp. But only about password autofill.

Safari generates it's 'strong' password into a sign-in form. Not a sign-up form. Only the user's password will work in sign-in form, not generated. Obvious.

I made a few tries to disable it with advice from here. But without results.

BTW. It was easy to fix with angular binding. So. This code will work 4 you only in case of using Angular2+ in the web layer.

<mat-form-field appearance="fill">
  <mat-label>Enter your password</mat-label>
  <input #pwd 
         matInput
         [type]="pwd.value.length === 0 ? 'text': 'password'"
         formControlName="passwordCtrl"
  required>
</mat-form-field>

Attribute [type] use one side binding with "[", "]". And automatically set value by the condition "(condition) ? option1: option2". If no symbols in the input - then the type is 'text'.

And not very 'clever' Safari browser doesn't perform autofill. So. Goal reached. Autofill disabled.

After more than 1 symbol in the input field. Type changes to 'password' very fast. And the user has no idea about something that happened. The type of the field is 'password'.

Also, it works with (keypressed) Event. Or using [(ngModel)]="pwd" instead of #pwd. And access by reactive forms.

But the basic thing that solved the problem for my cases - angular binding.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJariView Question on Stackoverflow
Solution 1 - HtmlIan BoydView Answer on Stackoverflow
Solution 2 - HtmlRichard perrisView Answer on Stackoverflow
Solution 3 - HtmldsuessView Answer on Stackoverflow
Solution 4 - HtmlVadizarView Answer on Stackoverflow
Solution 5 - HtmlEric McCormickView Answer on Stackoverflow
Solution 6 - HtmldontwakemeupView Answer on Stackoverflow
Solution 7 - HtmlBenView Answer on Stackoverflow
Solution 8 - HtmlS MView Answer on Stackoverflow
Solution 9 - HtmlbokorbenView Answer on Stackoverflow
Solution 10 - HtmlvendoView Answer on Stackoverflow
Solution 11 - HtmlIuliia ArtiukhView Answer on Stackoverflow
Solution 12 - HtmlbortunacView Answer on Stackoverflow
Solution 13 - HtmlimillardView Answer on Stackoverflow
Solution 14 - HtmlIkromView Answer on Stackoverflow
Solution 15 - HtmlFrançoisView Answer on Stackoverflow
Solution 16 - Htmluser767644View Answer on Stackoverflow
Solution 17 - HtmlMohamad HamoudayView Answer on Stackoverflow
Solution 18 - HtmlNikita DanilovView Answer on Stackoverflow