Lots of sites appear to support https but don't use secure cookies. I want to make my site use secure cookies but to allow for some content to be accessed using http instead.
许多网站似乎支持https但不使用安全cookie。我想让我的网站使用安全cookie,但允许使用http访问某些内容。
A sensible way to do this appears to be to have a secure cookie for the real session, and a non-secure cookie which is just a flag to say if the user is logged in or not (to display different things in the header, like a logout link instead of a login link). This cookie wouldn't contain any "real" session information and is just so that the site can show pages slightly differently for logged-in users compared to logged-out ones on http portions of the site.
一个合理的方法是为真实会话提供一个安全的cookie,以及一个非安全的cookie,它只是一个标志,表示用户是否登录(在标题中显示不同的内容,如注销链接而不是登录链接)。此cookie不包含任何“真实”会话信息,只是为了使网站可以显示登录用户与网站http部分登出的页面略有不同的页面。
Having the whole site as https is another option but this appears to be quite a bit slower than plain http and so is not really ideal.
将整个站点作为https是另一种选择,但这似乎比普通的http慢得多,所以不是很理想。
Why don't sites use this kind of set-up and have secure cookies? The possibility of cookie theft seems to make secure cookies a necessity nowadays. Is there a better way to achieve the same thing?
为什么网站不使用这种设置并拥有安全的cookie?饼干盗窃的可能性似乎使安全饼干成为必需品。是否有更好的方法来实现同样的目标?
4 个解决方案
#1
The solution you propose seems like it would work, as long as you don't mind non-authorized people being able to view the non-secure (http) part of the site 'as if they are logged in' - ie as long as the http part of the site does not contain any sensitive information, and the only difference between logged in and not-logged-in users is something harmless in the header.
您提出的解决方案似乎可行,只要您不介意未经授权的人员能够查看网站的非安全(http)部分,就好像他们已登录一样 - 即只要该站点的http部分不包含任何敏感信息,登录和未登录用户之间的唯一区别是标题中的无害。
The reason it is not used very often may be one of:
它不经常使用的原因可能是以下之一:
- This scenario may just not be very common. Usually if you care enough to make part of your site secure, you'd restrict the login session just to that secure part, or you'd make the entire site always use HTTPS (like Paypal).
- Pre-existing solutions exist which are secure and which are capable of more than this, for example logging in someone at an HTTPS login form and maintaining that session while transferring them back to HTTP.
OpenID's an example. Also think flickr or gmail: their sign in page is always HTTPS, but once the session's started you migrate back to HTTP while maintaining the session securely.
这种情况可能不是很常见。通常,如果您足够关心网站的一部分是安全的,那么您只需将登录会话限制在该安全部分,或者您将整个网站始终使用HTTPS(如Paypal)。
存在预先存在的解决方案,这些解决方案是安全的并且能够超过这个,例如以HTTPS登录表单登录某人并在将其转移回HTTP时维护该会话。 OpenID就是一个例子。还要考虑flickr或gmail:他们的登录页面始终是HTTPS,但是一旦会话开始,您将迁移回HTTP,同时安全地维护会话。
Update (Aug 2014)
更新(2014年8月)
Since I wrote this back in 2009, the practice of having a secure connection for the login screen but dropping back to HTTP once logged in has all but disappeared.
自从我在2009年写这篇文章以来,登录屏幕安全连接但登录后退回到HTTP的做法几乎消失了。
The overhead of using HTTPS side-wide is not seen as much of a big deal anymore. The new SPDY protocol pioneered by Google (now evolved into HTTP/2) is supported cross-browser and by major web servers and improves HTTPS speed.
在整个边界使用HTTPS的开销不再是一个大问题。谷歌率先推出的新SPDY协议(现已演变为HTTP / 2)支持跨浏览器和主要Web服务器,并提高了HTTPS速度。
And lastly, privacy is seen as more important than ever, even for actions that aren't critical to the authentication, such as writing comments, uploading photos, and more.
最后,隐私被视为比以往任何时候都更重要,即使是对身份验证不重要的操作,例如撰写评论,上传照片等。
Google has even said recently that sites which are HTTPS-only will start to benefit in search engine rankings.
谷歌最近甚至表示,仅限HTTPS的网站将开始受益于搜索引擎排名。
#2
From a security standpoint, you should never trust any content sent over a non-secured connection. So with that in mind, then it is safe to use a cookie sent over an unencrypted connection only if the cost of theft or misuse of that cookie is approximately zero.
从安全角度来看,您永远不应该信任通过非安全连接发送的任何内容。因此,考虑到这一点,只有当盗窃或滥用该cookie的成本大约为零时,才能安全地使用通过未加密连接发送的cookie。
With that in mind, most sites are designed such that the data isn't allowed to "leak" between the channels. After all, data coming from the encrypted side is usually privileged, and therefore shouldn't be allowed in the normal channel, while data coming from the unencrypted channel is potentially spoofed, and shouldn't be trusted.
考虑到这一点,大多数站点的设计使得数据不允许在通道之间“泄漏”。毕竟,来自加密端的数据通常是特权的,因此不应该在正常信道中被允许,而来自未加密信道的数据可能是欺骗性的,并且不应该被信任。
If you have data that doesn't fit those generalizations, then feel free to do with it as you please.
如果您的数据不符合这些概括,那么请随意使用它。
#3
Transferring session cookies over HTTP has been bothering me for a while. I think the technique you described is the only sane way to secure cookies while making it possible for logged in users to browse HTTP pages as if being logged in. However, I've rarely seen this implemented.
通过HTTP传输会话cookie一直困扰着我。我认为您所描述的技术是保护cookie的唯一理智方式,同时使登录用户可以像登录一样浏览HTTP页面。但是,我很少看到这个实现。
Why don't sites use this kind of set-up and have secure cookies?
为什么网站不使用这种设置并拥有安全的cookie?
I think the main reason for lack of adoption is risk management:
我认为缺乏采用的主要原因是风险管理:
- Stealing session tokens via eavesdropping is much harder than e.g. cross-site scripting (assuming there is a vulnerability). You need access to the network (e.g. user's LAN or ISP). Thus, according to risk-based prioritization developers should tackle XSS issues first because it provides a much bigger attack surface (the probability of an attack is much higher).
- The same is true for CSRF and UI redressing (aka click-jacking).
- If the business impact of sessions being hacked is high (e.g. storing credit cards for later use in a web shop), you might be better off restricting your whole site to HTTPS.
通过窃听窃取会话令牌比例如更难跨站点脚本(假设存在漏洞)。您需要访问网络(例如用户的LAN或ISP)。因此,根据基于风险的优先级划分,开发人员应首先解决XSS问题,因为它提供了更大的攻击面(攻击的可能性要高得多)。
CSRF和UI纠正(也称为点击顶升)也是如此。
如果被黑客入侵的会话的业务影响很大(例如存储信用卡以便以后在网上商店中使用),那么最好将整个网站限制为HTTPS。
Another reason can be usability concerns: With your proposed scheme you're effectively managing two concurrent sessions for a single user. This is easy enough as long as the logged-in-flag is the only state stored in the insecure session. If you can also change settings like language and country from within both sessions it can get messy (to implement or use).
另一个原因可能是可用性问题:使用您提出的方案,您可以有效地为单个用户管理两个并发会话。只要登录标志是存储在不安全会话中的唯一状态,这就很容易了。如果您还可以在两个会话中更改语言和国家/地区等设置,则可能会变得混乱(实现或使用)。
Is there a better way to achieve the same thing?
是否有更好的方法来实现同样的目标?
From The Web Application Hacker's Handbook:
来自Web应用程序黑客手册:
If HTTP cookies are being used to transmit tokens, these should be flagged as
secure
to prevent the user's browser from ever transmitting them over HTTP. If feasible, HTTPS should be used for every page of the application, including static content such as help pages, images, and so on.如果使用HTTP cookie来传输令牌,则应将这些cookie标记为安全,以防止用户的浏览器通过HTTP传输它们。如果可行,应该为应用程序的每个页面使用HTTPS,包括静态内容,如帮助页面,图像等。
Seriously, make the whole site use HTTPS. A few years back this might not have been feasible mainly because of CDNs not providing HTTPS support. However, today it's mainly a question of balancing development and operational costs.
说真的,让整个网站使用HTTPS。几年前,这可能不太可行,主要是因为CDN不提供HTTPS支持。但是,今天主要是平衡开发和运营成本的问题。
#4
I'm fully aware that the recommended practice is to just force SSL on the entire site. However, there are certainly unique cases where being able to pick and choose between HTTP and HTTPS could come in handy.
我完全清楚建议的做法是在整个站点上强制使用SSL。但是,有一些独特的情况,能够在HTTP和HTTPS之间进行选择可以派上用场。
I was running into a similar scenario as @Dsavid Gardner. My company uses a third party vendor to manage our store portion of our site, and that store resides on the subdomain "https://store.mysite.com". We have 15 years worth of video content, and our current video management vendor breaks when a video is embedded in an SSL. (I'm guessing it's pulling in resources from HTTP domains, but that's another problem for another day)
我遇到了与@Dsavid Gardner类似的情景。我的公司使用第三方供应商来管理我们网站的商店部分,该商店位于子域名“https://store.mysite.com”上。我们有15年的视频内容,当视频嵌入SSL时,我们当前的视频管理供应商会中断。 (我猜它是从HTTP域中提取资源,但这是另一天的另一个问题)
Sure, I could purchase an SSL and go through the process of debugging two, third-party vendors, as well as doing a search and replace on our entire database (or an .htaccess file hack, but I digress) to correct any HTTP resource links, just to be able to have a message in the header say "Welcome 'YourName'", but that just seems like overkill.
当然,我可以购买SSL并完成调试两个第三方供应商的过程,以及在我们的整个数据库(或.htaccess文件hack,但我离题)上进行搜索和替换以纠正任何HTTP资源链接,只是为了能够在标题中有一条消息说“欢迎'你的名字'”,但这似乎有点矫枉过正。
Here's a simple Javascript solution that I came up with that sets a site-wide, insecure cookie based off of the secure cookies that are already set.
这是我提出的一个简单的Javascript解决方案,它根据已经设置的安全cookie设置站点范围的,不安全的cookie。
First, I grabbed some javascript cookie functions. Go ahead and put this code in the secure portion of your site:
首先,我抓住了一些javascript cookie函数。继续将此代码放在您网站的安全部分:
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)===' ') {
c = c.substring(1,c.length);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length,c.length);
}
}
return null;
}
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+d.toUTCString();
/* Note, the W3 documents where I got this code didn't include the
option to set the domain. I added this and it allows the cookie
to be shared across sub-domains. Be sure not to add "www" */
document.cookie = cname + "=" + cvalue + "; " + expires + "; domain=.yourdomain.com";
}
/*Now we check our cookies on our secure server to find out if the user is
logged in or not. In my case, the First Name is stored as a cookie. */
var firstNameCookie = readCookie("the-secure-cookie-name");
//
if(!firstNameCookie){
/* If the cookie doesn't exist, then the person isn't logged in. Add
conditional logic here if you'd like (such as deleting any current
logged in cookies from the HTTP portion of the site) */
}
else {
/* otherwise, we have a successful login. By grabbing the cookie via
this javascript resting on the secure server, we haven't compromised our
security. However, if we set a cookie with javascript right now, it
won't be a secure cookie by default and we'll have access to it with
HTTP on the subdomain */
setCookie("HTTPfirstName", firstNameCookie, 1.5);
}
*/The clients first name is now accessible across subdomains in the cookie
entitled "HTTPfirstName" */
In this instance, the only thing we've leaked over to our HTTP server is the client's first name. However, if you would like even more security, you could set your server settings to only allow certain cookies (i.e. "firstNameCookie) to be accessed by an HTTP request, and that adds an extra layer of protection. You can learn how to do that here
在这种情况下,我们唯一泄漏到我们的HTTP服务器的是客户端的名字。但是,如果您希望获得更高的安全性,可以将服务器设置设置为仅允许HTTP请求访问某些cookie(即“firstNameCookie”),并添加额外的保护层。您可以了解如何执行此操作这里
Sure, this isn't the most ideal solution. In the future, I plan to implement SSL site-wide, but having a simple javascript function to replace it in the meantime is sure nice to have.
当然,这不是最理想的解决方案。在未来,我计划在站点范围内实现SSL,但是在此期间使用简单的javascript函数替换它确实很好。
#1
The solution you propose seems like it would work, as long as you don't mind non-authorized people being able to view the non-secure (http) part of the site 'as if they are logged in' - ie as long as the http part of the site does not contain any sensitive information, and the only difference between logged in and not-logged-in users is something harmless in the header.
您提出的解决方案似乎可行,只要您不介意未经授权的人员能够查看网站的非安全(http)部分,就好像他们已登录一样 - 即只要该站点的http部分不包含任何敏感信息,登录和未登录用户之间的唯一区别是标题中的无害。
The reason it is not used very often may be one of:
它不经常使用的原因可能是以下之一:
- This scenario may just not be very common. Usually if you care enough to make part of your site secure, you'd restrict the login session just to that secure part, or you'd make the entire site always use HTTPS (like Paypal).
- Pre-existing solutions exist which are secure and which are capable of more than this, for example logging in someone at an HTTPS login form and maintaining that session while transferring them back to HTTP.
OpenID's an example. Also think flickr or gmail: their sign in page is always HTTPS, but once the session's started you migrate back to HTTP while maintaining the session securely.
这种情况可能不是很常见。通常,如果您足够关心网站的一部分是安全的,那么您只需将登录会话限制在该安全部分,或者您将整个网站始终使用HTTPS(如Paypal)。
存在预先存在的解决方案,这些解决方案是安全的并且能够超过这个,例如以HTTPS登录表单登录某人并在将其转移回HTTP时维护该会话。 OpenID就是一个例子。还要考虑flickr或gmail:他们的登录页面始终是HTTPS,但是一旦会话开始,您将迁移回HTTP,同时安全地维护会话。
Update (Aug 2014)
更新(2014年8月)
Since I wrote this back in 2009, the practice of having a secure connection for the login screen but dropping back to HTTP once logged in has all but disappeared.
自从我在2009年写这篇文章以来,登录屏幕安全连接但登录后退回到HTTP的做法几乎消失了。
The overhead of using HTTPS side-wide is not seen as much of a big deal anymore. The new SPDY protocol pioneered by Google (now evolved into HTTP/2) is supported cross-browser and by major web servers and improves HTTPS speed.
在整个边界使用HTTPS的开销不再是一个大问题。谷歌率先推出的新SPDY协议(现已演变为HTTP / 2)支持跨浏览器和主要Web服务器,并提高了HTTPS速度。
And lastly, privacy is seen as more important than ever, even for actions that aren't critical to the authentication, such as writing comments, uploading photos, and more.
最后,隐私被视为比以往任何时候都更重要,即使是对身份验证不重要的操作,例如撰写评论,上传照片等。
Google has even said recently that sites which are HTTPS-only will start to benefit in search engine rankings.
谷歌最近甚至表示,仅限HTTPS的网站将开始受益于搜索引擎排名。
#2
From a security standpoint, you should never trust any content sent over a non-secured connection. So with that in mind, then it is safe to use a cookie sent over an unencrypted connection only if the cost of theft or misuse of that cookie is approximately zero.
从安全角度来看,您永远不应该信任通过非安全连接发送的任何内容。因此,考虑到这一点,只有当盗窃或滥用该cookie的成本大约为零时,才能安全地使用通过未加密连接发送的cookie。
With that in mind, most sites are designed such that the data isn't allowed to "leak" between the channels. After all, data coming from the encrypted side is usually privileged, and therefore shouldn't be allowed in the normal channel, while data coming from the unencrypted channel is potentially spoofed, and shouldn't be trusted.
考虑到这一点,大多数站点的设计使得数据不允许在通道之间“泄漏”。毕竟,来自加密端的数据通常是特权的,因此不应该在正常信道中被允许,而来自未加密信道的数据可能是欺骗性的,并且不应该被信任。
If you have data that doesn't fit those generalizations, then feel free to do with it as you please.
如果您的数据不符合这些概括,那么请随意使用它。
#3
Transferring session cookies over HTTP has been bothering me for a while. I think the technique you described is the only sane way to secure cookies while making it possible for logged in users to browse HTTP pages as if being logged in. However, I've rarely seen this implemented.
通过HTTP传输会话cookie一直困扰着我。我认为您所描述的技术是保护cookie的唯一理智方式,同时使登录用户可以像登录一样浏览HTTP页面。但是,我很少看到这个实现。
Why don't sites use this kind of set-up and have secure cookies?
为什么网站不使用这种设置并拥有安全的cookie?
I think the main reason for lack of adoption is risk management:
我认为缺乏采用的主要原因是风险管理:
- Stealing session tokens via eavesdropping is much harder than e.g. cross-site scripting (assuming there is a vulnerability). You need access to the network (e.g. user's LAN or ISP). Thus, according to risk-based prioritization developers should tackle XSS issues first because it provides a much bigger attack surface (the probability of an attack is much higher).
- The same is true for CSRF and UI redressing (aka click-jacking).
- If the business impact of sessions being hacked is high (e.g. storing credit cards for later use in a web shop), you might be better off restricting your whole site to HTTPS.
通过窃听窃取会话令牌比例如更难跨站点脚本(假设存在漏洞)。您需要访问网络(例如用户的LAN或ISP)。因此,根据基于风险的优先级划分,开发人员应首先解决XSS问题,因为它提供了更大的攻击面(攻击的可能性要高得多)。
CSRF和UI纠正(也称为点击顶升)也是如此。
如果被黑客入侵的会话的业务影响很大(例如存储信用卡以便以后在网上商店中使用),那么最好将整个网站限制为HTTPS。
Another reason can be usability concerns: With your proposed scheme you're effectively managing two concurrent sessions for a single user. This is easy enough as long as the logged-in-flag is the only state stored in the insecure session. If you can also change settings like language and country from within both sessions it can get messy (to implement or use).
另一个原因可能是可用性问题:使用您提出的方案,您可以有效地为单个用户管理两个并发会话。只要登录标志是存储在不安全会话中的唯一状态,这就很容易了。如果您还可以在两个会话中更改语言和国家/地区等设置,则可能会变得混乱(实现或使用)。
Is there a better way to achieve the same thing?
是否有更好的方法来实现同样的目标?
From The Web Application Hacker's Handbook:
来自Web应用程序黑客手册:
If HTTP cookies are being used to transmit tokens, these should be flagged as
secure
to prevent the user's browser from ever transmitting them over HTTP. If feasible, HTTPS should be used for every page of the application, including static content such as help pages, images, and so on.如果使用HTTP cookie来传输令牌,则应将这些cookie标记为安全,以防止用户的浏览器通过HTTP传输它们。如果可行,应该为应用程序的每个页面使用HTTPS,包括静态内容,如帮助页面,图像等。
Seriously, make the whole site use HTTPS. A few years back this might not have been feasible mainly because of CDNs not providing HTTPS support. However, today it's mainly a question of balancing development and operational costs.
说真的,让整个网站使用HTTPS。几年前,这可能不太可行,主要是因为CDN不提供HTTPS支持。但是,今天主要是平衡开发和运营成本的问题。
#4
I'm fully aware that the recommended practice is to just force SSL on the entire site. However, there are certainly unique cases where being able to pick and choose between HTTP and HTTPS could come in handy.
我完全清楚建议的做法是在整个站点上强制使用SSL。但是,有一些独特的情况,能够在HTTP和HTTPS之间进行选择可以派上用场。
I was running into a similar scenario as @Dsavid Gardner. My company uses a third party vendor to manage our store portion of our site, and that store resides on the subdomain "https://store.mysite.com". We have 15 years worth of video content, and our current video management vendor breaks when a video is embedded in an SSL. (I'm guessing it's pulling in resources from HTTP domains, but that's another problem for another day)
我遇到了与@Dsavid Gardner类似的情景。我的公司使用第三方供应商来管理我们网站的商店部分,该商店位于子域名“https://store.mysite.com”上。我们有15年的视频内容,当视频嵌入SSL时,我们当前的视频管理供应商会中断。 (我猜它是从HTTP域中提取资源,但这是另一天的另一个问题)
Sure, I could purchase an SSL and go through the process of debugging two, third-party vendors, as well as doing a search and replace on our entire database (or an .htaccess file hack, but I digress) to correct any HTTP resource links, just to be able to have a message in the header say "Welcome 'YourName'", but that just seems like overkill.
当然,我可以购买SSL并完成调试两个第三方供应商的过程,以及在我们的整个数据库(或.htaccess文件hack,但我离题)上进行搜索和替换以纠正任何HTTP资源链接,只是为了能够在标题中有一条消息说“欢迎'你的名字'”,但这似乎有点矫枉过正。
Here's a simple Javascript solution that I came up with that sets a site-wide, insecure cookie based off of the secure cookies that are already set.
这是我提出的一个简单的Javascript解决方案,它根据已经设置的安全cookie设置站点范围的,不安全的cookie。
First, I grabbed some javascript cookie functions. Go ahead and put this code in the secure portion of your site:
首先,我抓住了一些javascript cookie函数。继续将此代码放在您网站的安全部分:
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)===' ') {
c = c.substring(1,c.length);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length,c.length);
}
}
return null;
}
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+d.toUTCString();
/* Note, the W3 documents where I got this code didn't include the
option to set the domain. I added this and it allows the cookie
to be shared across sub-domains. Be sure not to add "www" */
document.cookie = cname + "=" + cvalue + "; " + expires + "; domain=.yourdomain.com";
}
/*Now we check our cookies on our secure server to find out if the user is
logged in or not. In my case, the First Name is stored as a cookie. */
var firstNameCookie = readCookie("the-secure-cookie-name");
//
if(!firstNameCookie){
/* If the cookie doesn't exist, then the person isn't logged in. Add
conditional logic here if you'd like (such as deleting any current
logged in cookies from the HTTP portion of the site) */
}
else {
/* otherwise, we have a successful login. By grabbing the cookie via
this javascript resting on the secure server, we haven't compromised our
security. However, if we set a cookie with javascript right now, it
won't be a secure cookie by default and we'll have access to it with
HTTP on the subdomain */
setCookie("HTTPfirstName", firstNameCookie, 1.5);
}
*/The clients first name is now accessible across subdomains in the cookie
entitled "HTTPfirstName" */
In this instance, the only thing we've leaked over to our HTTP server is the client's first name. However, if you would like even more security, you could set your server settings to only allow certain cookies (i.e. "firstNameCookie) to be accessed by an HTTP request, and that adds an extra layer of protection. You can learn how to do that here
在这种情况下,我们唯一泄漏到我们的HTTP服务器的是客户端的名字。但是,如果您希望获得更高的安全性,可以将服务器设置设置为仅允许HTTP请求访问某些cookie(即“firstNameCookie”),并添加额外的保护层。您可以了解如何执行此操作这里
Sure, this isn't the most ideal solution. In the future, I plan to implement SSL site-wide, but having a simple javascript function to replace it in the meantime is sure nice to have.
当然,这不是最理想的解决方案。在未来,我计划在站点范围内实现SSL,但是在此期间使用简单的javascript函数替换它确实很好。