7

我知道客户端 JavaScript 中的安全性要么不存在,要么非常困难。我知道我的服务器端代码最终应该决定它向谁提供数据或从谁那里接受数据。

就是说,以下是可以做的。“好的”我的意思是如果这是一些新流行的时尚酷网络应用程序上使用的方法。知道我不会看到“Super Cool Web App Hacked, change your passwords”,我晚上能不能睡觉?由于此实施,整个 HN 和 Reddit(或人们关心的任何其他信息来源)。

如果不安全。为什么?如何获取这些信息(用户名和密码)?

如果是安全的?你有多确定?为什么它是安全的?是什么阻止了我在我现在明显无能为力的情况下获取这些信息。

欢迎部分回答。只是寻求更好的理解。


编辑

我正在考虑一些人试图窃取用户凭据的情况。我的理解是 cookie 是不安全的,因为 1.)其他 javascript(通过 XSS 或其他方式)可以访问它们,并且因为 2.)它们以明文形式传递。我认为 SSL 会解决第二个问题,假设我能够防止 XSS。现在看来,cookie 现在是安全的,对吧?

我知道一些可能导致 cookie 不安全的浏览器漏洞。这就是让我问这个问题的原因。考虑到所有使 cookie 不安全的因素,这(下面的代码)是否更好?


http://jsfiddle.net/KTastrophy/vXEjm/1/或查看下面的代码(仅在 Chrome 中测试)

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <form id="login">
            <div>
                <label for="username">Username</label>
                <input id="username" name="username" type="text" />
            </div>
            <div>
                <label for="password">Password</label>
                <input id="password" name="password" type="password" />
            </div>
            <div>
                <input id="submit" name="submit" type="submit" value="Login" />
            </div>
        </form>
    </body>
    <script type="text/javascript">
        ;(function () {
            "use strict";
            var login, user = {};
            login = document.getElementById("login");
            login.onsubmit = function (event) {
                event.preventDefault();
                user.username = document.getElementById("username").value;
                user.password = document.getElementById("password").value;

                /*
                    use the username and password here to do
                    an API request over SSL using HTTP Auth
                 */
            }
        }());
    </script>
</html>
4

5 回答 5

7

当您处理存储在 JavaScript 中的敏感值时,您有两个主要的安全问题:

  1. 敏感值在源中可以作为纯文本查看。
  2. 页面上的另一个 JS 函数可以进入对象并提取这些值(即 XSS 攻击)。

当您在单个页面上运行来自多个来源的应用程序(例如,Facebook 应用程序)时,上述第二项变得更加相关。在这些情况下,您必须采取预防措施,不要通过对命名空间使用闭包来公开敏感变量。您实际上已经这样做了:您的user对象在闭包内声明。这可以防止页面上的任何其他 JS 函数能够访问该user对象。

在您的情况下,我假设页面上除了您自己的代码之外没有任何其他代码,并且注入的可能性很小——您的代码是安全的:)

编辑:将用户名和密码存储在 cookie 中不安全的原因在于,它在您关闭浏览器后位于您的计算机上。如果黑客可以访问该 cookie(通过多种方式),那么您可能会遇到麻烦。您在上面所做的事情是安全的,因为在浏览器关闭后,客户端没有存储任何内容(并且在浏览器打开时,其他 JS 无法访问您存储的值)。如果您想在 cookie 中放入一些东西,最好存储某种公共/私有身份验证密钥。对此有很多讨论,这里有一篇关于该主题的详尽的“最佳实践”文章:http: //jaspan.com/improved_persistent_login_cookie_best_practice

于 2012-08-01T23:09:48.750 回答
2

如果您存储的数据出现在源代码中,那么不会,toString可以使用函数的方法将函数体转换为源代码。

function f() {
  var cryptoKey = "ABGASDJEOTATJKASDTNM...";
}
alert(f);

如果数据被关闭而不是出现在源代码中,并且函数无法eval在其主体中调用,那么在现代解释器上是可以的。

较旧的 Netscape 解释器进行了扩展eval,因此它可以用于通过eval("nameOfLocalVariable", fnToStealFrom).

如果函数调用它的参数之一,那么它可以被窃取。

var f = (function () {
  var x = "secret";
  return function (a, b) { return a(b + x.length); };
})();
f(eval, "x//");

将窃取 EcmaScript 3 解释器和一些 EcmaScript 5 解释器的秘密。

于 2012-08-01T23:18:15.287 回答
1

将输入框的值保存在 javascript 值中非常好,因为自从用户输入它以来,他们显然知道它。

然而!通常不赞成在任何地方将用户密码存储为纯文本。

编辑

SSL 将使恶意观察者很难拦截和重新创建消息(如果有足够的时间,这并非不可能,但足以让大多数 Web 使用它作为安全)。暂时将单个密码存储在该页面上输入的 javascript 变量中是可以的。但是,不要服务器以纯文本形式发送它,否则您会在头条新闻中醒来。

于 2012-08-01T23:24:37.887 回答
0

不,您可以并且需要做的是:

  • 保护您的数据库。将密码存储为加盐哈希等。
  • 确保连接。您需要使用 SSL。

在客户端 javascript 代码中可能没有安全性。用户以纯文本形式输入所有数据,因此页面中运行的每个脚本都可以访问它。因此,您需要防止 XSS。当然,cookie 可直接用于在您的域上运行的每个脚本,而隐藏在某些函数范围内的数据不是“全局变量”,但每个恶意脚本都可以像您自己的应用程序一样访问它。

@您的代码:是的,没有人可以user从外部访问该对象。但是每个人都可以访问密码输入元素,并且每个人都可以劫持浏览器对象以窥探 api 请求。

于 2012-08-02T00:13:21.667 回答
0

正如您的示例所显示的那样,您是完全安全的。

但是,这并不能取代 cookie。在您的示例中,您将密码存储在本地代码中,但与 cookie 不同,这些值以后永远不能使用。

最好根本不存储该值,并通过 ssl 使用传统的 http 身份验证。

于 2012-08-02T00:31:06.327 回答