安全 cookie 和混合 https/http 站点使用

发布于 2024-07-15 18:34:19 字数 407 浏览 6 评论 0原文

许多网站似乎支持 https,但不使用安全 cookie。 我想让我的网站使用安全 cookie,但允许使用 http 访问某些内容。

做到这一点的一个明智的方法似乎是为真实会话提供一个安全 cookie,以及一个非安全 cookie,它只是一个标志来说明用户是否登录(在标头中显示不同的内容,例如注销链接而不是登录链接)。 此 cookie 不会包含任何“真实”会话信息,只是为了使网站在网站的 http 部分上为登录用户显示的页面与为注销用户显示的页面略有不同。

将整个网站设置为 https 是另一种选择,但这似乎比纯 http 慢很多,因此并不是很理想。

为什么网站不使用这种设置并拥有安全 cookie? 如今,cookie 被盗的可能性似乎使得安全 cookie 成为必需品。 有没有更好的方法来实现同样的目标?

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.

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.

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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不离久伴 2024-07-22 18:34:19

您提出的解决方案似乎可行,只要您不介意非授权人员能够“就像登录一样”查看网站的非安全(http)部分 - 即只要该网站的 http 部分不包含任何敏感信息,登录用户和未登录用户之间的唯一区别是标头中无害的内容。

它不经常使用的原因可能是以下之一:

  • 这种情况可能不太常见。 通常,如果您非常关心网站部分的安全,您可以将登录会话限制为该安全部分,或者您可以让整个网站始终使用 HTTPS(如 Paypal)。
  • 现有的解决方案既安全又具有更多功能,例如通过 HTTPS 登录表单登录某人并在将其传输回 HTTP 时维护该会话。 OpenID 就是一个例子。 还可以考虑 flickr 或 gmail:它们的登录页面始终是 HTTPS,但是一旦会话开始,您就可以迁移回 HTTP,同时安全地维护会话。

更新(2014 年 8 月)

自从我写这篇文章以来早在 2009 年,登录屏幕采用安全连接但登录后又返回 HTTP 的做法几乎消失了。

侧面使用 HTTPS 的开销不再被认为是一个大问题。 由 Google 首创的新 SPDY 协议(现已演变成 HTTP/2)受到跨浏览器和主要 Web 服务器的支持,并提高了 HTTPS 速度。

最后,隐私被认为比以往任何时候都更加重要,即使对于对身份验证不重要的操作也是如此,例如撰写评论、上传照片等。

谷歌最近甚至表示,仅使用 HTTPS 的网站将开始在搜索引擎排名中受益。

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.

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.

Update (Aug 2014)

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.

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.

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.

风蛊 2024-07-22 18:34:19

从安全角度来看,您永远不应该信任通过不安全连接发送的任何内容。 因此,考虑到这一点,只有当盗窃或滥用 cookie 的成本大约为零时,使用通过未加密连接发送的 cookie 才是安全的。

考虑到这一点,大多数站点的设计都不允许数据在渠道之间“泄漏”。 毕竟,来自加密端的数据通常具有特权,因此不应在正常通道中被允许,而来自未加密通道的数据则可能被欺骗,并且不应该被信任。

如果您的数据不符合这些概括,请随意处理。

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.

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.

走过海棠暮 2024-07-22 18:34:19

通过 HTTP 传输会话 cookie 一直困扰着我一段时间。 我认为您所描述的技术是保护 cookie 的唯一明智方法,同时使登录用户能够像登录一样浏览 HTTP 页面。但是,我很少看到这种实现。

为什么网站不使用这种设置并拥有安全 cookie?

我认为缺乏采用的主要原因是风险管理

  • 通过窃听窃取会话令牌比跨站点脚本编写(假设存在漏洞)要困难得多。 您需要访问网络(例如用户的 LAN 或 ISP)。 因此,根据基于风险的优先级,开发人员应该首先解决 XSS 问题,因为它提供了更大的攻击面(攻击的可能性更高)。
  • CSRF 和 UI 修复(又名点击劫持)也是如此。
  • 如果被黑客攻击的会话对业务的影响很大(例如,存储信用卡以供以后在网上商店使用),那么您最好将整个网站限制为 HTTPS。

另一个原因可能是可用性问题:通过您提出的方案,您可以有效地管理单个用户的两个并发会话。 只要登录标志是存储在不安全会话中的唯一状态,这就很容易了。 如果您还可以在两个会话中更改语言和国家/地区等设置,那么它可能会变得混乱(实施或使用)。

是否有更好的方法来实现同样的目标?

来自Web应用程序黑客手册 :

如果使用 HTTP cookie 来传输令牌,则应将这些令牌标记为安全,以防止用户的浏览器通过 HTTP 传输它们。 如果可行,应用程序的每个页面都应使用 HTTPS,包括帮助页面、图像等静态内容。

说真的,让整个网站都使用 HTTPS。 几年前,这可能不可行,主要是因为 CDN 不提供 HTTPS 支持。 然而,今天主要是平衡开发和运营成本的问题。

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.

Why don't sites use this kind of set-up and have secure cookies?

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.

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:

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.

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.

南巷近海 2024-07-22 18:34:19

我完全清楚,建议的做法是在整个网站上强制使用 SSL。 然而,在某些特殊情况下,能够在 HTTP 和 HTTPS 之间进行选择可能会派上用场。

我遇到了与@Dsavid Gardner 类似的情况。 我的公司使用第三方供应商来管理我们网站的商店部分,该商店位于子域“https://store .mysite.com”。 我们拥有 15 年的视频内容,而当视频嵌入 SSL 时,我们当前的视频管理供应商就会崩溃。 (我猜它是从 HTTP 域中提取资源,但这是另一天的另一个问题)

当然,我可以购买 SSL 并完成调试两个第三方供应商的过程,以及进行搜索和替换在我们的整个数据库(或 .htaccess 文件黑客,但我离题)上纠正任何 HTTP 资源链接,只是为了能够在标头中显示一条消息“欢迎'YourName'”,但这似乎有点矫枉过正。

这是我提出的一个简单的 Javascript 解决方案,它根据已设置的安全 cookie 设置站点范围的不安全 cookie。

首先,我获取了一些 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" */

在本例中,我们泄漏到 HTTP 服务器的唯一内容是客户端的名字。 但是,如果您想要更高的安全性,您可以将服务器设置设置为仅允许 HTTP 请求访问某些 cookie(即“firstNameCookie”),这会增加额外的保护层。 您可以在此处了解如何执行此操作

当然,这不是最理想的解决方案。将来,我计划在站点范围内实现 SSL,但同时拥有一个简单的 javascript 函数来替换它肯定是件好事。

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.

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)

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.

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.

First, I grabbed some javascript cookie functions. Go ahead and put this code in the secure portion of your site:

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文