登录/会话 cookie、Ajax 和安全
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/661599/
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
Login/session cookies, Ajax and security
提问by supertodda
I'm trying to determine the most secure method for an ajax based login form to authenticate and set a client side cookie. I've seen things about XSS attacks such as this:
我正在尝试为基于 ajax 的登录表单确定最安全的方法来验证和设置客户端 cookie。我见过关于 XSS 攻击的事情,例如:
How do HttpOnly cookies work with AJAX requests?
and
和
http://www.codinghorror.com/blog/archives/001167.html
http://www.codinghorror.com/blog/archives/001167.html
So, I guess my core questions are...
所以,我想我的核心问题是......
1) Is using pure ajax to set cookies secure, if so, what is the most secure method (httpOnly + SSL + encrypted values, etc.)?
1)使用纯ajax设置cookie是否安全,如果是,最安全的方法是什么(httpOnly + SSL +加密值等)?
2) Does a pure ajax method involve setting the cookie client side? Is this at all secure?
2)纯ajax方法是否涉及设置cookie客户端?这完全安全吗?
3) Is setting cookies this way reliable across all major browsers/OSs?
3) 以这种方式设置 cookie 在所有主要浏览器/操作系统上都可靠吗?
4) Would using a hidden IFrame be any more secure (calling a web page to set the cookies)?
4) 使用隐藏的 IFrame 会更安全吗(调用网页来设置 cookie)?
5) If possible, does anybody have code for this (PHP is my backend)?
5) 如果可能的话,有人有这方面的代码吗(PHP 是我的后端)?
My goal is to set the cookies and have them available for the next call to the server without navigating away from the page.
我的目标是设置 cookie 并使它们可用于下一次对服务器的调用,而无需离开页面。
I really want to nail down the consensus, most secure way to do this. Eventually, this code is planned to be made Open Source, so please no commercial code (or nothing that wouldn't stand up to public scrutiny)
我真的很想确定共识,最安全的方式来做到这一点。最终,此代码计划开源,因此请不要使用商业代码(或任何经不起公众的代码)
Thanks, -Todd
谢谢,-托德
回答by thomasrutter
The cookie needs to be generated server-side because the session binds the client to the server, and therefore the token exchange must go from server to client at some stage. It would not really be useful to generate the cookie client-side, because the client isthe untrusted remote machine.
It is possible to have the cookie set during an AJAX call. To the server (and the network) an AJAX call is simply an HTTP call, and any HTTP response by the server can set a cookie. So yes, it is possible to initiate a session in response to an AJAX call, and the cookie will be stored by the client as normal.
So, you can use AJAX to do the logging in process in the same was as you could have just relied on a POST from a form on the page. The server will see them the same way, and if the server sets a cookie the browser will store it.
Basically, client-side Javascript never needs to be able to know the value of the cookie (and it is better for security if it doesn't, which can be achieved using the "httponly" cookie extension honored by recent browsers). Note that further HTTP calls from the client to the server, whether they are normal page requests or they are AJAX requests, will include that cookie automatically, even if it's marked httponly and the browser honors that extension. Your script does not need to be 'aware' of the cookie.
You mentioned using HTTPS (HTTP over SSL) - that prevents others from being able to read information in transit or impersonate the server, so it's very handy for preventing plain text transmission of the password or other important information. It can also help guard against network based attacks, though it does not make you immune to everything that CSRF can throw you, and it does not at all protect you against the likes of session fixation or XSS. So I would avoid thinking of HTTPS as a fix-all if you use it: you stillneed to be vigilant about cross-site scripting and cross-site request forgery.
(see 1. I sort of combined them)
Given that the cookie is set by the server in its HTTP response headers, yes it is reliable. However, to make it cross-browser compatible you still need to ensure logging in is possible when AJAX is unavailable. This may require implementing an alternative that is seen only when there is no Javascript or if AJAX isn't available. (Note: now in 2014, you don't need to worry about browser support for AJAX anymore).
It would not change the security. There would be no need for it, except that I have seen hidden iframes used before to 'simulate' AJAX before - ie make asyncronous calls to the server. Basically, however you do it doesn't matter, it's the server setting the cookie, and the client will accept and return the cookie whether it does it by AJAX or not.
cookie 需要在服务器端生成,因为会话将客户端绑定到服务器,因此令牌交换必须在某个阶段从服务器到客户端。生成 cookie 客户端实际上并没有用,因为客户端是不受信任的远程机器。
可以在 AJAX 调用期间设置 cookie。对于服务器(和网络),AJAX 调用只是一个 HTTP 调用,服务器的任何 HTTP 响应都可以设置 cookie。所以是的,可以启动会话以响应 AJAX 调用,并且 cookie 将由客户端正常存储。
因此,您可以使用 AJAX 来执行登录过程,就像您可以依赖页面上表单中的 POST 一样。服务器将以相同的方式查看它们,如果服务器设置了 cookie,浏览器将存储它。
基本上,客户端 Javascript 永远不需要能够知道 cookie 的值(如果不知道,它的安全性会更好,这可以使用最近浏览器支持的“httponly”cookie 扩展来实现)。请注意,从客户端到服务器的进一步 HTTP 调用,无论是普通页面请求还是 AJAX 请求,都会自动包含该 cookie,即使它被标记为 httponly 并且浏览器支持该扩展名。您的脚本不需要“知道”cookie。
您提到使用 HTTPS(基于 SSL 的 HTTP)——它可以防止其他人读取传输中的信息或冒充服务器,因此它对于防止密码或其他重要信息的纯文本传输非常方便。它还可以帮助防范基于网络的攻击,尽管它不会让您免受 CSRF 可能抛出的所有问题,而且它根本不能保护您免受会话固定或 XSS 之类的攻击。因此,如果您使用 HTTPS,我会避免将其视为万能的:您仍然需要警惕跨站点脚本和跨站点请求伪造。
(参见 1. 我将它们组合在一起)
鉴于 cookie 是由服务器在其 HTTP 响应标头中设置的,是的,它是可靠的。但是,为了使其跨浏览器兼容,您仍然需要确保在 AJAX 不可用时可以登录。这可能需要实现仅在没有 Javascript 或 AJAX 不可用时才能看到的替代方案。(注意:现在是 2014 年,您不再需要担心浏览器对 AJAX 的支持)。
它不会改变安全性。不需要它,除了我之前看到隐藏的 iframe 之前用于“模拟”AJAX - 即对服务器进行异步调用。基本上,无论你怎么做都没有关系,这是服务器设置 cookie,客户端将接受并返回 cookie,无论它是否通过 AJAX 执行。
For the most part, whether you use AJAX or not does not affect the security all that much as all the real security happens on the server side, and to the server an AJAX call is just like a non-AJAX call: not to be trusted. Therefore you'll need to be aware of issues such as session fixationand login CSRFas well as issues affecting the session as a whole like CSRFand XSSjust as much as you would if you were using no AJAX. The issues don't really change when using AJAX except, except, I guess, that you may make more mistakes with a technology if you're less familiar with it or it's more complicated.
在大多数情况下,无论您是否使用 AJAX 都不会影响安全性,因为所有真正的安全性都发生在服务器端,而对服务器而言,AJAX 调用就像非 AJAX 调用:不被信任. 因此,您需要注意诸如会话固定和登录 CSRF 之类的问题,以及影响整个会话的问题(如CSRF和XSS),就像不使用 AJAX 时一样。使用 AJAX 时,这些问题并没有真正改变,除了我猜,如果您不太熟悉某项技术或它更复杂,您可能会在使用该技术时犯更多错误。
Answer updated September 2014
2014 年 9 月更新的答案

