禁用Safari自动填充用户名和密码

时间:2014-03-26 13:05:31

标签: html security autocomplete safari autofill

您可能已经知道,Safari有一个讨厌的自动填充错误,无论您是否设置autocomplete="off",它都会填写电子邮件,用户名和密码字段。

这是一个基本形式:

<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在页面加载时自动填充这些字段,就像它应该做的那样,干得好!

如果您将autocomplete="off"添加到字段和/或表单元素中,Safari仍会自动填充这些字段:

<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>

即使这不起作用:

<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>

...因为Safari会查找那些<label>元素,如果它们包含“电子邮件”,“密码”等单词并继续自动填充。

Aaaahhhhha!我想,并尝试了这个:

<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>

...并使用JavaScript将%TAGS%替换为真实姓名。 Safari自动填充开始。无论您是否在替换时设置了10秒超时。

那么,这真的是唯一的选择吗?

<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>

我希望不是吗?

更新:@skithund pointed out in Twitter,即Safari is getting a 4.0.3 update,其中提到“登录自动填充”。有谁知道这个更新是否会解决这个问题?

18 个答案:

答案 0 :(得分:35)

我遇到了同样的问题。虽然我的解决方案并不完美,但似乎有效。基本上,Safari似乎在寻找带有密码和用户名的输入字段,并且总是试图填充它。因此,我的解决方案是在Safari可以填充的当前版本之前添加一个假的用户名和密码字段。我尝试使用style="display: none;",但这不起作用。所以,最终,我只使用了style="position:absolute; top:-50px;",这隐藏了输入字段,看起来工作正常。我不想使用JavaScript,但我猜你可以用JavaScript隐藏它。

现在Safari从未自动填写我的用户名和密码字段。

答案 1 :(得分:25)

浏览器忽略autocomplete=off的原因是因为有些网站试图禁用自动填写密码。

这是错误的。

2014年7月,Firefox是最后一个最终实施此更改的主要浏览器,以忽略任何试图关闭自动填充密码的网站。

  

关于我们的HTML表单自动完成功能的一个主要用户投诉是“它不起作用 - 我没有看到我之前输入的任何文本。”在调试此类案例时,我们通常会发现该网站已使用提供的属性明确禁用了该功能,但当然,用户并不知道该网站已经这样做并且只是假设IE是错误的。根据我的经验,当隐藏或替换功能时,用户通常会责怪浏览器,而不是网站。

任何网站试图绕过浏览器的偏好都是错误的,这就是浏览器忽略它的原因。没有理由知道为什么网站应该尝试禁用密码保存。

  • Chrome忽略它
  • Safari忽略它
  • IE忽略它
  • Firefox忽略它
  

此时,Web开发人员通常会抗议“但我不会在任何地方都这样做 - 只有少数几点才有意义!”即使这是真的,不幸的是,这还不行另一种情况是浏览器无法区分它们。请记住,弹出窗口曾经是网络浏览体验的一个快乐,有用的部分,直到广告商的滥用使他们成为各地用户的祸根。不可避免的是,所有浏览器都开始阻止弹出窗口,打破了那些使用具有良好品味和自由裁量权的弹出窗口的“好”网站。

如果我是特殊的snowflake

,该怎么办?

有些人提出了一个很好的用例:

  

我有一个共享的公共区域,自助式计算机。我们不希望有人(意外或有意)保存他们的密码,以便下一位用户可以使用它。

这不违反声明:

  

任何网站试图绕过浏览器的偏好都是错误的

这是因为在共享信息亭的情况下:

  • 网络服务器不具备古怪的政策
  • 客户用户代理具有奇怪的政策

浏览器(共享计算机)是要求 it 不尝试保存密码的计算机。

阻止浏览器保存密码的正确方法
是配置浏览器不保存密码。

由于您已锁定并控制此自助服务终端计算机:您可以控制设置。这包括保存密码的选项。

在Chrome和Internet Explorer中,您可以使用组策略(例如注册表项)配置这些选项。

来自Chrome Policy List

  

AutoFillEnabled

     

启用自动填充

     

数据类型:布尔值(REG_DWORD)

     

Windows注册表位置:Software \ Policies \ Chromium \ AutoFillEnabled

     

说明:启用Chromium的自动填充功能,并允许用户使用以前存储的信息(如地址或信用卡信息)自动填写网络表单。如果禁用此设置,用户将无法访问自动填充。如果启用此设置或未设置值,则自动填充将保持在用户的控制之下。这将允许他们配置自动填充配置文件并自行决定是否打开或关闭自动填充功能。

请将这个词告诉企业经理,试图禁用自动填写密码是错误的。浏览器故意无视任何试图这样做的人是错误的。那些人应该停止做错事。™

换句话说

换句话说:

  • 如果用户浏览器
  • 错误&#34;请输入您最喜欢的婚前姓名的第一个颜色。&#34; 以获取新密码
  • 用户
  • 不想他们的浏览器
  • 更新他们的密码,
  • 然后他们
  • 将点击 Nope

enter image description here

  • 如果我想保存我的HIPPA密码:那是我的权利
  • 如果我想保存我的PCI密码:那是我的权利
  • 如果我想为用户保存&#34;新密码&#34; :那是我的权利
  • 如果我想保存一次性密码:那是我的权利
  • 如果我想保存我的&#34;第一个颜色最喜欢的少女&#34; 回答:那是我的权利。

过度统治用户的意愿不是你的工作。这是他们的浏览器;不是你的。

答案 2 :(得分:16)

修正:浏览器通过只读模式自动填充并在焦点上设置可写

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

(焦点=鼠标点击并在字段中标记)

更新: Mobile Safari将光标设置在字段中,但不显示虚拟键盘。 New Fix像以前一样工作,但处理虚拟键盘:

<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();  }" />

现场演示https://jsfiddle.net/danielsuess/n0scguv6/

// UpdateEnd

说明:浏览器会自动将凭据填写到错误的文本字段吗?

好的,你刚才注意到:

  

Safari自动填充功能。无论[字段名称是什么] @Jari

并且假设:

  

Safari似乎在寻找带有密码和用户名的输入字段,并且总是试图填写它 @ user3172174

有时候我会在Chrome和Safari上发现这种奇怪的行为,当中有相同格式的密码字段时。我想,浏览器会查找密码字段以插入您保存的凭据。然后用户名自动填充到最近的textlike-input字段中,该字段出现在DOM中的密码字段之前(仅因为观察而猜测)。由于浏览器是最后一个实例,您无法控制它,

有时甚至autocomplete = off也不会阻止将凭据填入错误的字段,但不会阻止用户或昵称字段。

上面的readonly-fix对我有用。

答案 3 :(得分:11)

将css添加到输入将隐藏safari按钮伪元素,用户将无法使用自动完成

&#13;
&#13;
input::-webkit-contacts-auto-fill-button, 
input::-webkit-credentials-auto-fill-button {
  visibility: hidden;
  pointer-events: none;
  position: absolute;
  right: 0;
}
&#13;
&#13;
&#13;

答案 4 :(得分:7)

在通过Apple's Safari HTML pages进行扫描而未在自动完成时找到任何之后,我进行了一些搜索和思考。

在阅读有关Apple讨论的a (mildly) related question之后,我记得默认是不允许记住密码等(可以在iDevice系统设置中或在提示符下启用)。由于Apple已将此功能移出浏览器并进入其(专有的,i)操作系统(screen shots on this article),我相信他们完全忽略了HTML表单/字段属性。

除非他们改变了对此功能的心态,因为我确信这是他们的预期行为,在他们锁定的设备上,我会假设这不会消失。对于原生iOS应用程序,这可能有所不同。绝对保持表单autocomplete =“off”和hopefully they'll one day get back to the HTML5 standard为该功能。

我知道这不包括任何解决方法,但我认为如果你接受它是iDevices上的非浏览器“功能”,它是有意义的(以Apple的方式)。

答案 5 :(得分:5)

这个问题已经得到了成功的回答,但截至今天的日期,如果没有做出一些奇怪的特殊修改,解决方案对我没有用 - 所以如果我决定来,我会在这里注意它自己的参考像其他人一样回到它身边。

  • 在dom中输入真实电子邮件后,虚假输入需要
  • 虚假输入需要假标签。
  • 假标签不能绝对定位。
  • 无法使用显示,可见性或不透明度来隐藏虚假元素。

我找到的唯一解决方案是使用overflow: hidden剪切虚假元素的可见性。

<label for="user_email">Email</label>
<input autocomplete="off" type="text" value="user@email.com" 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">

对于记录,这个黑客有用的特殊情况是管理员正在编辑其他用户的个人资料,而Safari正在用管理员的电子邮件替换用户的电子邮件。我们已经决定,对于这个Safari“功能”创建的小量(但令人沮丧)的支持请求,不值得维护一个似乎需要随着Safari收紧而发展的黑客攻击,而是为这些用户提供支持关于如何关闭自动填充。

答案 6 :(得分:2)

据我所知,我不敢相信这仍是一个问题。上面的解决方案对我来说不起作用,因为safari似乎知道元素何时没有显示或不在屏幕外,但以下内容对我有效:

<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>

希望这对某人有用!

答案 7 :(得分:1)

我也被Safari的奇怪的默认自动完成行为所咬,但不是完全禁用它,我设法按照https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands的指导方针让它适用于我。

具体来说,我将autocomplete="username"放在用户名字段上,将autocomplete="password-current"放在密码字段上。这告诉浏览器哪些字段是自动填充的,而不是猜测它,并修复了我的用例的自动完成。

此方法适用于“首先发送电子邮件”登录表单(密码字段无法立即显示,例如Google登录)以及可见的用户名和密码字段的常规登录表单。

答案 8 :(得分:0)

删除<form>元素。为了保持表单行为,您可以监听keypress事件,以便输入字段以处理按下的enter键。以防万一我也删除input type="submit"。您可以使用button type="button"

答案 9 :(得分:0)

浏览器程序员似乎认为他们比网站编写者更了解。虽然允许用户保存密码有时很方便,但有时候它会带来安全风险。对于那些时候,这种解决方法可能有所帮助:

首先使用传统的文字输入,而不是密码&#39;类型。

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

然后 - 如果您愿意 - 将焦点设置为输入字段。

<BODY onLoad="fitform()">

将JS放在页面的末尾。

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

现在你有一个传统的表格领域。这有什么用呢?
更改该输入的CSS样式,使其使用的字体是全部的子弹&#39;而不是字符。

<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>

是的,你可以整理一下&#39;代码,并添加.svg。

无论哪种方式,最终结果都与“真实”无法区分。密码输入,浏览器无法保存。

如果你想要字体,那就是here。 它是使用CorelDraw创建的,并使用在线webfont转换实用程序进行转换。 (dot_webfont_kit.zip 19.3k)

我希望这会有所帮助。

答案 10 :(得分:0)

比使用JS清除内容更好 - 只需伪造密码字段:

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

password类型加倍使浏览器处于不确定状态,因此它只会自动填充用户名

fake_pass input不应具有name属性以保持$_POST清洁!

答案 11 :(得分:0)

我的问题:我在管理区域中有一个部分,允许用户设置所有语言值,其中一些包含单词&#34;密码&#34;,&#34;电子邮件& #34;,&#34;电子邮件地址&#34;我不希望这些值被用户的详细信息填充,它们用于创建另一种语言的翻译。这是一个有效的例外,可以绕过浏览器的偏好&#34;提及。

我的解决方案:我只是创建了替代名称:

$name = str_replace('email','em___l',$name);
$name = str_replace('password','pa___d',$name);
<input type="text" name="<?=$name?>" id="<?=$name?>" />

然后在发布表单时:

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

这是唯一对我有用的方法。

答案 12 :(得分:0)

此处提到的CSS display: none解决方案对我不起作用(2016年10月)。我用JavaScript解决了这个问题。

我不介意浏览器记住密码,但希望防止自动填充错误。就我而言,一个带有密码字段且没有关联用户名字段的表单。 (Drupal 7站点中的用户编辑表单,其中仅在某些操作中需要密码字段。)无论我尝试什么,Safari都会找到自动填充密码的用户名的受害者字段(例如,之前可视化放置的字段)。 / p>

我在Safari执行自动填充后立即恢复原始值。我只在页面加载后的前2秒尝试这个。可能更低的价值也可以。我的测试显示自动填充发生在页面加载后大约250毫秒(尽管我想这个数字很大程度上取决于页面的构造和加载方式)。

这是我的JavaScript代码(使用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);
}

答案 13 :(得分:0)

您可以尝试这种变体。这个对我有用。 如果您更改一次字段值,Safari将再次更改它。如果用户在此字段中单击,则此后Safari将不会自动更改该值。

  $.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;
        }
    });

答案 14 :(得分:0)

我在Mobile Safari 10.3.1中使用React的SPA突然遇到了同样的问题

在所有经过测试的浏览器中,我甚至不需要任何棘手的解决方法,甚至是Mobile Safari IOS 10.2

但是,由于10.3.1用户名或密码将填入字段提及字样&#39;密码&#39;,&#39;电子邮件&#39;,&#39;用户名&# 39;以主动记忆选项登录后的任何形式。似乎已经对渲染的DOM树进行了分析&#39;使用全文搜索然后用户代理填写数据而不尊重任何自动完成=&#34;关闭&#34;设置。 在场地的占位符文本上也会出现funnyli。因此,当您不希望在此数据无效的地方使用预先填写的用户名或密码时,您必须非常关心命名。

经过数小时调查的唯一解决方案是此处发布的解决方案。 提供名为&#34; email&#34;的输入字段。并隐藏包含div的高度:0px,overflow:hidden。

答案 15 :(得分:0)

您可以通过将此属性添加到密码输入中来禁用它

autocomplete="new-password"

答案 16 :(得分:0)

对我来说,这个问题非常严重。但仅涉及密码自动填充。

Safari将其“强”密码生成为登录表单。不是注册表格。只有用户的密码才能以登录形式使用,而不是生成。显而易见。

我做了一些尝试,并从这里建议禁用它。但是没有结果。

顺便说一句。使用角度绑定很容易修复。所以。仅当在Web层中使用Angular2 +时,此代码才对您有用4。

<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>

属性[type]使用带有“ [”,“]”的一侧绑定。并通过条件“(condition)?option1:option2”自动设置值。如果输入中没有符号-则类型为“文本”。

不是很“聪明”的Safari浏览器不会执行自动填充。所以。达成目标。自动填充功能已禁用。

在输入字段中超过1个符号。将类型快速更改为“密码”。用户不知道发生了什么。字段的类型为“密码”。

此外,它与(按键)事件一起使用。或使用[(ngModel)] =“ pwd”代替#pwd。并通过反应形式进行访问。

但是解决我的问题的最基本的方法是角度绑定。

答案 17 :(得分:0)

只需在名称中输入搜索,Safari 就会忽略自动填充字段。

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