没有httpOnly的Cookie,它有多不安全?

时间:2015-08-11 16:55:46

标签: javascript security authentication cookies

开发一个需要设置cookie的Web应用程序httpOnly = false

因为,我找不到其他方法来通过身份验证cookie(用于检查用户是否已成功登录)从服务器端通过我前端的Javascript访问。然后,此cookie用于向我的服务器端发送AJAX请求(添加到标头中)。 (如果我错了,请纠正我,并建议我任何其他方式)

我的问题:

httpOnly = false有多不安全?是否足够安全,只需强制它使用cookieSecureOption = true,以便始终通过HTTPS发送。

如何保护它免受XSS攻击?

3 个答案:

答案 0 :(得分:1)

“非HttpOnly cookie”本身并不是一个漏洞。

“HttpOnly cookie”可降低XSS攻击的风险。也就是说,任何攻击者将脚本注入您的网站都无法获取此cookie的值,从而保护会话。

如果您的应用程序需要使用cookie值作为标题添加,那么您不能将此cookie标记为“HttpOnly”。您可以更改请求处理程序以查找cookie中的值而不是标题中的值(因此您可以设置标记),但这可能会使您的网站面临CSRF的风险。最安全的方法是让您的处理程序通过“HttpOnly”cookie检查授权,并在标头中使用另一个标记值(“non-HttpOnly”)来检查CSRF。如果这些值不同,例如在encrypted token patternsynchronizer token pattern中,攻击者只通过XSS检索一个值没有多大价值,因为他们无法使用它来授权请求​​。请注意,任何XSS漏洞通常都是一个比CSRF漏洞更大的问题,因为攻击者可能总是使用他们的XSS攻击来直接从您的站点提交请求,但要完成攻击要困难得多。至少在“HttpOnly”中,他们无法从您的网站获取auth cookie以便远程登录。

您提到的另一个Cookie标志是secure flag。这会将cookie范围限制为仅限https连接,如果您使用https(也建议使用),则建议使用此范围。这不会影响JavaScript是否可以访问该值。

如果您确实使用了“非HttpOnly cookie”,那么您仍然可以通过以下方式缓解XSS的威胁。

  1. 将所有脚本代码移动到外部js文件中并设置Content Security Policy以防止执行任何内联脚本。

  2. 设置anti-XSS响应标头以缓解反映的XSS攻击:

    X-XSS-Protection:1;模式=块

  3. 确保在输出时正确编码所有用户输入(例如,<在HTML中变为&lt;)并针对您的应用程序运行Web安全扫描程序。

答案 1 :(得分:0)

如果您没有标记HTTPOnly,那么您的用户仍然比其他用户更容易受到XSS攻击,因为仍然可以从JavaScript访问Cookie。根据您的描述,您不需要从JavaScript访问变量,只需从服务器端访问cookie(这仍然可以通过标记HTTPOnly,每次请求包括AJAX调用发送cookie)来检索身份验证信息。 Secure标志和HTTPOnly标志可以抵御完全不同的攻击。<​​/ p>

答案 2 :(得分:0)

有一种混合方式可以做到这一点。我说杂交是因为它涉及你所做的一半以及bksi在评论中提到的混合。

由于我不知道您的完整场景,因此这个答案假设您只是在寻找一种方法来验证用户,然后再允许他们进行更改或启动进程服务器端;登录,查看帐户页面等。你永远不应该完全依赖于httpOnly = false我建议将它与以下内容一起使用。

稳固解决方案
当用户成功登录时设置普通cookie,这不需要通过HTTPS发送,尽管它会很好。此cookie应该是随机生成的会话令牌。我通常在他们的用户ID(假设你使用数据库)和他们登录时的时间戳哈希(PHP中的md5加密)和这确保令牌是唯一的。

现在您已将令牌作为cookie保存在本地计算机上,并确保将此令牌保存在服务器端的PHP会话中。现在,只要他们访问页面或发送了AJAX请求,您就可以将本地cookie与PHP会话值服务器端进行比较。这是验证与服务器交互的用户的最快方法。如果值匹配,则它们是合法的。

现在这不完全安全。可以随时编辑本地cookie,这是我们通常不关心的事情,因为这只会通过使会话无效来损害用户。另一方面,一个狡猾的黑客可以改变PHP会话,这可能会使其他用户无效,因为他们的会话被删除或被劫持。黑客必须获得合法的会话令牌并使cookie匹配。

更好的解决方案
1)在服务器端,您可以使用数据库而不是PHP会话。该过程保持不变,但现在您需要做更多的工作来保持数据库中的会话表是最新的。通常,这是通过使用时间戳保存令牌并在每次检查令牌时更新此时间戳来完成的。如果检查了令牌并且上一个时间戳确实很旧(您决定了多长时间),则可以通过销毁其本地cookie并让他们再次登录来取消对用户进行身份验证。但这会占用更多资源,并且会降低流量负载较大的网站的速度。

2)使用双重身份验证的形式。这将使用90%的PHP会话来处理简单的事情,但是当一个非常重要的过程出现时,比如更新个人信息或提供信用卡信息,也要检查数据库。这将需要在用户计算机上保存两个不同的cookie。一个用于检查PHP会话以进行身份​​验证,另一个用于检查数据库。这种情况对于黑客来说非常难以突破更重要的事情,因为他们需要找出令牌和数据库,这是不容易窃取的。

最后的想法
这是一个相当安全的答案,但您仍应实施额外的安全预防措施。您似乎误解了Cookie的工作原理;你最近的评论听起来像你使用cookies和ajax倒退,但也许我误解了。我是这样做的:

[User]-> Tries logging in to website with a login form
[Server]-> Checks this information against the database Pass, log 'em in.
[Server]->  Generate and set a random token as a cookie

我在这里使用PHP并且通常使用诸如sessionToken之类的名称存储此cookie。这个cookie现在立即存在于用户计算机上,我们服务器总是可以访问它的服务器端;我们可以随时打电话。这并不是真正安全,因为人们可以复制cookie,而不会在我们发送给他们时知道/窃取它。我会在一分钟内处理。

[服务器] - GT;创建一个具有相同令牌的PHP会话(会话ID:abc123)服务器端。

这是安全方面的第一步。 PHP会话不容易窃取或破解。因此,即使有人在试图在计算机上使用它时窃取了我们的用户令牌cookie,它也会失败。这是一个虚荣的用户:

[User]-> (PHP session id: abc123) Tries to access secured page or content. PHP session is called up and is checked against the cookie token. If they equal each other this attempt passes.

此处用户在他们不知道的服务器上有一个会话,该会话识别他们是谁,并且只能由服务器访问;通常。这是您的AJAX请求发挥作用的地方。每次用户尝试执行您想要查看的内容时,如果他们甚至被允许这样做,请通过AJAX将请求发送到验证用户身份的PHP脚本。它所做的就是发回PASS或FAIL。然后你可以使用AJAX或Javascript来做你需要的任何事情。这是一个黑客的例子:

[Hacker]-> Steals a cookie from a user over a cafe's wifi.
[Hacker]-> Tries to access the website you are on with it.
[Server]-> (PHP session id: ???) Doesn't have one, destroy the cookie and ask this user (the hacker) to login again.

这是我能提供的尽可能多的信息和帮助。您的最新评论开始听起来像您应该在Stackoverflow上发布的新问题。