javascript 防止用户通过 Firebug/Chrome Dev Tools 查找密码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30013032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 11:29:52  来源:igfitidea点击:

Prevent user to find password through Firebug/Chrome Dev Tools

javascriptsecuritydombrowserclient

提问by Manoj Kumar

Hidden Password

隐藏密码

For the passport input field:

对于护照输入字段:

<input type="text" required="" tabindex="2" class="std_textbox" placeholder="Enter your account password." id="pass" name="pass">

When the <input type="password">is changed to <input type="text">The password is revealed. This can be risky in systems which have saved passwords or generated from Password managers.

<input type="password">更改为<input type="text">密码显示。这在已保存密码或从密码管理器生成的系统中可能存在风险。

Revealed Password

泄露密码

Can client side encryption be used in here? How can it be implemented?

这里可以使用客户端加密吗?如何实施?

回答by Eric

Short answer:It can not be prevented, unfortunately. This is because all client-side code (JavaScript) is modifiable by the client itself - thus making a client-based security system vulnerable.

简短回答:不幸的是,这是无法阻止的。这是因为所有客户端代码 (JavaScript) 都可以由客户端本身修改 - 从而使基于客户端的安全系统容易受到攻击。

The only workable solution I can think of, is to store a hashedrepresentation of the password, instead of the raw password. This will (if you disregard hash-bruteforce attacks) keep the raw password safe.

我能想到的唯一可行的解​​决方案是存储密码的散列表示,而不是原始密码。这将(如果您忽略散列暴力攻击)保持原始密码的安全。

A hash is a representation of the original text, and is non-reversable. That is, the original string of characters can not be retrieved by any algorithm, using only the hash. Examples of hash' is MD5 and SHA. This technique is commonly used in routers, where password often is stored in the browser.

散列是原始文本的表示,并且是不可逆的。也就是说,不能通过任何算法检索原始字符串,只能使用散列。散列的例子是 MD5 和 SHA。这种技术通常用于路由器,其中密码通常存储在浏览器中。

Clarification: Never store your passwords in plain-text, and if you want to adopt this technique of pre-entered password; the hashing and/or encryption must occur on server side.

澄清:永远不要以纯文本形式存储您的密码,如果您想采用这种预先输入密码的技术;散列和/或加密必须发生在服务器端。

回答by Ely

I saw solutions in different answers. In all of them, it is just harder to see the password, but it does not prevent someone from seeing it.

我在不同的答案中看到了解决方案。在所有这些中,只是更难看到密码,但这并不能阻止某人看到它。

Note: On client side JavaScript objects can be manipulated and inspected. In the solutions provided in other answers I could easily access the password information.

注意:在客户端可以操作和检查 JavaScript 对象。在其他答案中提供的解决方案中,我可以轻松访问密码信息。



As others stated, you cannot prevent the user from viewing the password using developer tools on client side.

正如其他人所说,您无法阻止用户使用客户端的开发人员工具查看密码。

I could not think of a use case, but you mentioned automatic form fillerand the Remember meoption.

我想不出用例,但你提到了自动填表记住我选项。

Automatic form filler, as far as I know are master password protected. They should be; I would not use one if I could not switch it on or off securely. In this case it is my responsibility to log out, whenever I am in situation of sharing a computer.

自动填表,据我所知是受主密码保护的。他们应该是; 如果我不能安全地打开或关闭它,我就不会使用它。在这种情况下,每当我处于共享计算机的情况下时,我都有责任注销。

Remember meoption, as often promoted by web sites, should only be used when it is your personal computer and you do not expect to share your device with another person. Don't use it or make sure no one else uses your account. Again, it is your responsibility.

记住我选项,通常由网站推广,仅当它​​是您的个人计算机并且您不希望与他人共享您的设备时才应使用。不要使用它或确保没有其他人使用您的帐户。再次,这是你的责任。

Now, you still see a need to prevent such an attack. All I can come up with is the following:

现在,您仍然认为需要防止此类攻击。我能想到的只有以下几点:

  1. There is no viable solution on client side. So your solution must work on server side.
  2. On server side you can encrypt or hash the function. Please see this questionfor more details. I will discuss this further in the rest of this answer. You can opt for either solution, however implementation differs.
  1. 客户端没有可行的解决方案。所以你的解决方案必须在服务器端工作。
  2. 在服务器端,您可以加密或散列函数。有关更多详细信息,请参阅此问题。我将在本答案的其余部分进一步讨论这一点。您可以选择任一解决方案,但实施方式有所不同。

If you use encryption, then you can always decrypt.

如果您使用加密,那么您始终可以解密。

That might help you in the following scenario: Keep the password always encrypted. They should always match. However, when the user wants to change his password it will be clear text. The user cannot type it in an encrypted form. You have to solve that. There are solutions. I am sure you get that.

在以下情况下这可能对您有所帮助: 始终保持密码加密。它们应该始终匹配。但是,当用户想要更改他的密码时,它将是明文。用户不能以加密形式键入它。你必须解决这个问题。有解决方案。我相信你明白了。

If you use (encrypted) hashing, then it is very hard to crack. You cannot decrypt it.

如果您使用(加密)散列,则很难破解。你不能解密它。

This might help you in the following scenario: The server sends only the hashed version. This way no attacker can use this information. You need to design it accordingly, but I imagine you figure that out too.

这可能在以下情况下对您有所帮助: 服务器仅发送散列版本。这样,攻击者就无法使用这些信息。你需要相应地设计它,但我想你也明白这一点。

Having said that, I really don't see an acceptable use case for your requirement.

话虽如此,我真的没有看到您的要求可以接受的用例。

Let me explain why. You want to prevent an attacker from seeing the password in case a user remembers the passwords or uses an automatic form filler. Well, if an attacker is able to access a user's computer he would be able to simply log in, why bother seeing the password?

让我解释一下原因。您希望防止攻击者看到密码,以防用户记住密码或使用自动填表。好吧,如果攻击者能够访问用户的计算机,他将能够简单地登录,为什么还要查看密码呢?

There is a reason why companies like Google or Facebook did not bring in a solution for your use case. The went another path and trying to push for increased security by 2-factor authentication

Google 或 Facebook 等公司没有为您的用例提供解决方案是有原因的。走了另一条路,并试图通过两因素身份验证来提高安全性

If you can use that, do it. It does not solve the issue completely, but you can expect it to increase security. In particular it is harder for an attacker.

如果你可以使用它,那就去做吧。它并不能完全解决问题,但您可以期待它提高安全性。尤其是攻击者更难。

回答by Chavez

As it is clientside, there is no real way to prevent this. In terms of a security model: we can't trust the client. On the other hand, however, there is no real way to implement this differently without the use of a third party device.

由于它是客户端,因此没有真正的方法可以防止这种情况。在安全模型方面:我们不能信任客户端。然而,另一方面,如果不使用第三方设备,就没有真正的方法来以不同的方式实现这一点。

If you're willing to go through the trouble of having a third party device assist in authentication: have the website generate and show a random seed, have the device ask for the seed and password to generate a hash, and authenticate on the site using the hash. Of course, the hash will still be visible if you use a web debugger, but at least there's no point in storing/reading it as the hash will differ for each session. This isn't completely secure either, by the way, as this method is prone to chosen plaintext attack.

如果您愿意让第三方设备协助进行身份验证的麻烦:让网站生成并显示随机种子,让设备要求提供种子和密码以生成哈希,并使用哈希值。当然,如果您使用 Web 调试器,哈希值仍然可见,但至少存储/读取它没有意义,因为每个会话的哈希值都不同。顺便说一下,这也不是完全安全的,因为这种方法容易受到选择性明文攻击。

Kudos if you're willing to go through all this trouble though. I suppose you could write an app for this to have a smartphone function as the third party device.

不过,如果您愿意经历所有这些麻烦,那就太好了。我想您可以为此编写一个应用程序,将智能手机功能用作第三方设备。

回答by naim shaikh

Absolutely not. You can't prevent the end user to manipulate the DOMfrom Developer tools or firebug.

绝对不。您无法阻止最终用户通过开发人员工具或 firebug操作DOM

Use of any client side trick can't prevent user to do that. Until or unless the browser restrict user's from doing that.

使用任何客户端技巧都不能阻止用户这样做。直到或除非浏览器限制用户这样做。

回答by Jacob Finamore

    I believe the issue you are facing is multiple people using the same computer, and if one user saves their password on your site, then any one else that visits the site on the same pc will be able to manipulate the field to reveal the password.

    我相信您面临的问题是多人使用同一台计算机,如果一个用户将他们的密码保存在您的网站上,那么在同一台电脑上访问该网站的任何其他人都可以操纵该字段以显示密码。

    One way of preventing this from happening is to disable the auto-complete. autocomplete="off"Place this code in the input element and even if the password is saved, it shouldn't show up. <input autocomplete="off" type="text" required="" tabindex="2" class="std_textbox" placeholder="Enter your account password." id="pass" name="pass">

    防止这种情况发生的一种方法是禁用自动完成。autocomplete="off"将此代码放在输入元素中,即使保存了密码,它也不应该显示出来。<input autocomplete="off" type="text" required="" tabindex="2" class="std_textbox" placeholder="Enter your account password." id="pass" name="pass">

Pros
You don't have to worry about users sharing computers, and passwords being revealed for the most part.
Cons
Users may think their passwords are saved (and they can still save passwords) but when they get to your site, it will not show up.
NOTEThis isn't the full-proof way of preventing users form manipulating the form and retrieving other users passwords.

优点
您不必担心共享计算机的用户以及大多数情况下的密码会被泄露。
缺点
用户可能认为他们的密码已保存(并且他们仍然可以保存密码),但是当他们到达您的站点时,它不会显示。
注意这不是防止用户操纵表单和检索其他用户密码的完全方法。

As a side note, if the site does not refresh after entering a password and user name the web browser will not ask to save the password. For example, using an ajax call in stead of form submit.

附带说明一下,如果网站在输入密码和用户名后没有刷新,Web 浏览器将不会要求保存密码。例如,使用 ajax 调用代替表单提交。

You can use JavaScript to erase the text inside the password field when the page loads. A better style would be adding the field when the page loads with JavaScript like so:var x = document.createElement("INPUT"); x.setAttribute("type", "password");

当页面加载时,您可以使用 JavaScript 擦除密码字段内的文本。更好的样式是在页面加载 JavaScript 时添加字段,如下所示:var x = document.createElement("INPUT"); x.setAttribute("类型", "密码");

An alternative to the autocomplete="off" autocomplete alternativeIt involves generating a name from the backend and using it as the name of the fields so that the autocomplete will never know where to put your users saved data

autocomplete="off"自动完成替代方案的替代方案它涉及从后端生成一个名称并将其用作字段的名称,以便自动完成功能永远不会知道将用户保存的数据放在哪里

回答by Tom Marulak

Well it is not possible with current technology. Like others stated, you still can inspect all the client side code and try to manipulate the DOM.

嗯,目前的技术是不可能的。就像其他人所说的那样,您仍然可以检查所有客户端代码并尝试操作 DOM。

The other solution is to implement like banking login. Randomise the password sequence every time user login. For example if password length is 10, give user three password fields, ask the sequence of password eg. 3rd, 5th, 10th. This will change every time user try to login. And in the server side you compare them.

另一种解决方案是实现类似银行登录。每次用户登录时随机设置密码序列。例如,如果密码长度为 10,则给用户三个密码字段,询问密码的顺序,例如。第三、第五、第十。每次用户尝试登录时,这都会改变。在服务器端你比较它们。

回答by Schlaus

You can't, and you shouldn't. This is not a security issue you should be tackling on your website. It's up to the user to keep their passwords safe. If I have the ability to use the dev console or otherwise inject javascript on your page, no matter what you do the user's passwords will still be compromised.

你不能,也不应该。这不是您应该在网站上解决的安全问题。保护密码的安全取决于用户。如果我有能力使用开发控制台或以其他方式在您的页面上注入 javascript,无论您做什么,用户的密码仍然会受到损害。

If a user chooses to save their passwords in their browser, then it's up to them to prevent them from falling into wrong hands, and there's absolutely nothing you can do about it on your site. In fact, if you're using Chrome and have passwords saved, navigate to chrome://settings/passwords and click on some password fields.

如果用户选择将他们的密码保存在浏览器中,那么他们有责任防止他们落入坏人之手,而且您在网站上绝对无能为力。事实上,如果您使用 Chrome 并保存了密码,请导航到 chrome://settings/passwords 并单击一些密码字段。

Other answers talk about hashing passwords etc. That's something you should definitely do, but on your server. You could of course hash or encrypt a password before sending it to your server (and you really should too, using https), but that's a completely different issue.

其他答案谈论散列密码等。这是您绝对应该做的事情,但在您的服务器上。您当然可以在将密码发送到您的服务器之前对其进行散列或加密(您确实也应该使用 https),但这是一个完全不同的问题。

回答by SaidbakR

You can use a simple Javascript code to store the password value in a variable onblur and then restore it onfoucs or/and onsubmit.

您可以使用简单的 Javascript 代码将密码值存储在变量 onblur 中,然后在 onfoucs 或/和 onsubmit 中恢复它。

Look at the following demo code and its online demo here:

此处查看以下演示代码及其在线演示:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
<script>
password = '';
function setPasswordBack(){
  showPassword();
}
function hidePassword(){
  p = document.getElementById('pass');
  password = p.value;
  p.value = '*********';
}
function showPassword(){
  p = document.getElementById('pass');  
  p.type= "password"; 
  p.value = password;
}
</script>
</head>
<body>
<form action="" method="get" onsubmit="setPasswordBack()">
<input type="password" value="" name="password" id="pass" onblur="hidePassword()" onfocus="showPassword()" />
<input type="submit" />
</form>
</body>
</html>

It is clear that solution is JavaScript dependent solution, so in the case of disabling javascript, you may use noscriptasking for JavaScript enabled browser.

很明显,该解决方案是依赖于 JavaScript 的解决方案,因此在禁用 javascript 的情况下,您可以使用noscript要求启用 JavaScript 的浏览器。

回答by Tero Tolonen

Well, you can't.

嗯,你不能。

But then again. There is one way of course to prevent user never seeing it using Developer console - never display the INPUT field which has the password.

但话又说回来。当然有一种方法可以防止用户使用开发人员控制台永远不会看到它 - 永远不要显示具有密码的 INPUT 字段。

The alternative would be to emulate the field's behaviour so that it seems to be there, but isn't. I have not found a technically sound solution yet how it could be done, but here is one example how it might be done: (updated) http://jsfiddle.net/858kef4h/

另一种方法是模拟该领域的行为,使其似乎存在,但实际上并不存在。我还没有找到一个技术上合理的解决方案,但它是如何完成的,但这是一个如何完成的示例:(更新)http://jsfiddle.net/858kef4h/

In this example, the idea is to create a DIV based pseudofield which looks like password INPUT and is listening keypresses from the user and saving the value to a JavaScript variable

在这个例子中,我们的想法是创建一个基于 DIV 的伪字段,它看起来像密码 INPUT 并且正在监听用户的按键并将值保存到 JavaScript 变量

<div class="pwField">
  <div class="pwData"></div>
  <div class="cursor"><div class="tfarea"></div></div>
</div>

This simple hack just has three state variables for password, focus state and the hidden textarea

这个简单的hack只有密码、焦点状态和隐藏文本区域的三个状态变量

var pw = "", bHasFocus = false, tfArea;

The "cursor" class is toggled on / off using JavaScript to emulate real cursor

使用 JavaScript 打开/关闭“cursor”类以模拟真实的光标

setInterval( function() {
   $(".cursor").toggleClass("blink");
},600);

When the div is clicked it creates a textarea at the place of the cursor and focuses to it.

单击 div 时,它会在光标位置创建一个 textarea 并聚焦到它。

$(".pwField").on("click", function() {
    // enable cursor and create element if needed
    $(".pwField").addClass("active");
    if(tfArea) { // if already created, just focus to the field
        tfArea.focus(); 
        bHasFocus = true;
        return;
    }
    tfArea = document.createElement("textarea");
    tfArea.value="";
    $(".tfarea").append(tfArea);
    tfArea.focus();   
    bHasFocus = true;
    $(tfArea).on("blur", function() {
        // disable cursor and exit
        $(".pwField").removeClass("active");
        bHasFocus = false; 
    });
});

Then you can listen to keyup/keydown and record the values

然后你可以听 keyup/keydown 并记录值

$(document).keydown(function(  ) {
    if(!bHasFocus) return;
    pw = tfArea.value;
    // print asterisks
    $(".pwData").html( asterisks( pw.length ) );
});

And when you are ready to login, the value is in the "pw" variable.

当您准备登录时,该值位于“pw”变量中。

This dynamically created TEXTAREA may go unnoticed by the automatic password managers, because it is not the kind of INPUT -field the Password Managers are expecting to see.

这个动态创建的 TEXTAREA 可能不会被自动密码管理器注意到,因为它不是密码管理器期望看到的 INPUT 字段。

The user which edits the field can naturally inspect the value of this element using the Chrome Developer tools, but the point here is, if the PW manager does not consider that field as a password -field it is not filling it with the password of the previous user.

编辑该字段的用户可以使用 Chrome 开发者工具自然地检查该元素的值,但这里的重点是,如果 PW 管理器不将该字段视为密码 - 字段,则不会填充它的密码以前的用户。

I don't recommend using this, this was just made out of curiosity.The idea was to show that even though you can not prevent the user from seeing the elements, you may still be able hide the result from Password Managers. But like the old saying goes, "you can fool some of them some of the time, but not all of them all of the time".

我不建议使用这个,这只是出于好奇。这个想法是为了表明即使您无法阻止用户看到这些元素,您仍然可以对密码管理器隐藏结果。但就像那句老话,“你可以在某些时候欺骗他们中的一些人,但不能一直欺骗他们”

The user experience is not the same as with standard input, but it could be improved. One problem is also that, even though you wanted to prevent the password to be shown, that may be what the users really want. They may want to user the Password Manager. But in this case you are out of luck anyway.

用户体验与标准输入不同,但可以改进。还有一个问题是,即使您想阻止显示密码,这也可能是用户真正想要的。他们可能想要使用密码管理器。但在这种情况下,无论如何你都不走运。

There may also be problems with the click, focus and blur with different browsers, they may not work with mobile devices as you expect. If this kind of hack is ever used, you should carefully tested. It could be used, if you know exactly what kind of browsers the users are using and you know they have JavaScript enabled.

不同浏览器的点击、聚焦和模糊也可能存在问题,它们可能无法像您预期的那样在移动设备上工作。如果曾经使用过这种黑客,您应该仔细测试。如果您确切地知道用户使用的是哪种浏览器并且您知道他们启用了 JavaScript,则可以使用它。

EDIT:I tested the approach with some mobile devices and it seemed to somewhat work, but with iPad, and noticed that placing the hidden textarea will still create a visible cursor and change the zoom, so now the hidden textarea is placed inside the pseudocursor DIV and the zoom should follow it.

编辑:我在一些移动设备上测试了这种方法,它似乎有些工作,但是对于 iPad,并注意到放置隐藏的 textarea 仍然会创建一个可见的光标并更改缩放,所以现在隐藏的 textarea 被放置在伪光标 DIV 中并且缩放应该跟随它。

回答by Peleg

Note:I think you should avoid doing this as it will break basic browser functionality.

注意:我认为您应该避免这样做,因为它会破坏基本的浏览器功能。

But if you insist, you could make it harderfor someone to reveal the password by "delegating" the typing to another input field and populating the password field with random characters.

但是,如果您坚持,您可以通过将键入“委托”到另一个输入字段并用随机字符填充密码字段来使某人更难泄露密码。

Below is an example of one way to do so. Keep in mind that by no means does it preventsomeone from retrieving the password from the request body directly or if they find your 'hidden' delegate element.

下面是这样做的一种方法的示例。请记住,这绝不会阻止某人直接从请求正文中检索密码,也不会阻止他们找到您的“隐藏”委托元素。

!function() {

    var passwordEl, delegateEl;

    function syncPassword() {
        passwordEl.value = 
            Array(delegateEl.value.length + 1).join('*');
    }

    function createDelegate() {
        delegateEl = document.createElement('input');
        delegateEl.style.position = 'absolute';
        delegateEl.style.top = '-9999px';

        delegateEl
            .addEventListener('keyup', syncPassword, false);

        document.body.appendChild(delegateEl);
    }

    window.addEventListener('load', function() {
        passwordEl = document.getElementById('passwordId');
        createDelegate();

        // steal the focus from the password input
        passwordEl.addEventListener('focus', function(e) {
            e.preventDefault();
            delegateEl.focus();
        }, false);

        syncPassword(); // clear if was auto completed

    }, false);
}();

Now you have the option of re-filling your password input with the correct password on form submit, or simply have your server expect the password to arrive from the delegated field.

现在您可以选择在表单提交时使用正确的密码重新填写您的密码输入,或者只是让您的服务器期望密码从委托字段到达。

If you fancy, you could add the appropriate styling to the password field when the delegate field is focused and thus give the user the impression that they are still focused on the password field itself.

如果您愿意,可以在委托字段获得焦点时向密码字段添加适当的样式,从而让用户感觉他们仍然专注于密码字段本身。

But don't.

但是不要。