如何防止饼干中毒

时间:2009-10-27 19:17:16

标签: php security cookies

我将数据保存在cookie中,以便为下次登录时的用户进行身份验证(请记住我的选项)。这些数据经过加密和散列。

但问题出在这里:

任何人都可以拿这个cookie并把它放在另一台机器上,它会起作用。

我听说这叫做cookie中毒

我如何克服这个问题?

5 个答案:

答案 0 :(得分:4)

将计算机的IP地址和/或主机名存储在cookie(哈希值)以及当前的方案中,并对其进行验证。

答案 1 :(得分:3)

你真的无法阻止它,但你可以采取一些措施来使它变得更难,从而减少吸引力

  1. 要求用户在整个会话中使用https(443)。这可以防止任何中间人攻击嗅探cookie

  2. 一次只允许一个会话处于活动状态。第二个会话出现后,第一个会话无效。

  3. 要求用户在更改密码时进行提供旧密码(编辑:或电子邮件地址或其他可能导致帐户在登录后被盗的内容);这样可以防止有人劫持帐户并轻松更改密码。

  4. 会话cookie的生命周期非常有限 - 可能需要几个小时。

  5. 话虽如此,由于您打开了系统门,您可能希望确保不存储任何易于用户阅读的敏感信息。因此,例如,如果系统中有信用卡或SSN,请不要将其显示给用户。

答案 2 :(得分:2)

您所描述的威胁是攻击者会窃取用户的Cookie并使用它来访问该用户的会话。防止这种情况的一种方法是存储IP地址或主机名,如Daniel A White提到的那样,但如果不可能,则没有100%安全的方式来协商这一点。

以下是其他一些可以抵御此类攻击的选项:

  1. 对所有基于会话的网站流量使用HTTPS,并将Cookie设置为仅通过HTTPS传输。如果这是一个选项,这将防止中间人攻击。
  2. 设置一个额外的Cookie,其中包含随每个请求更改的随机值。如果随机值被多次使用,您知道劫持者已获得访问权限,您可以销毁会话以确保安全。

答案 3 :(得分:0)

甚至可以使用标识符来劫持会话(无论如何用于识别唯一会话)。在分配新密码之前询问旧密码的提示是可以的,但如果您支持“丢失我的密码”功能,则每次在帐户中更改关键信息(例如电子邮件)时都需要输入密码。

Google做了什么:它们允许您浏览登录到您帐户的“地点”(或计算机)(因为您可以在家中,工作中使用它等)并“关闭”这些连接。如果您不知道连接,您可以“关闭”它(关闭会话)并立即更改密码以确保劫持者不使用您的旧密码(如果密码已知密码)。

答案 4 :(得分:0)

Cookie 中毒不仅是 PHP 的问题.. 这解决了 .net

阻止 cookie 中毒的唯一方法是了解 cookie 并通过在造成永久性损坏之前停止响应来阻止 Web 应用程序中毒。

我帮助开发的 Web 应用程序防火墙 (https://www.nuget.org/packages/Walter.Web.FireWall) 做到了这一点,社区版是免费的,您会在检测到中毒时收到警报,并允许您通过其 OnCookiePoisoningIncident 事件进行处理。

/// <summary>
    /// If this creates a incident the firewall will queue the incident in the reporting workflows, if
    /// the email workflow is enabled an email to the firewall administrators will be send informing them about the incident 
    /// </summary>
    private void MyFireWall_OnCookiePoisoningIncident(object sender, FireWallCookieIncidentEventArgs e)
    {
        /* create a incident and block all access based on the firewall rules for cookie poisoning
        * you can not create an incident based on your own logic here
        * like:  
             
            e.AllowRaiseIncident = e.CookiePoisoning.CookieManipulations > 2;           

        * or when a non- served cookie was injected by checking for common attack patterns like "userId", "card" or "admin"
            e.AllowRaiseIncident =  e.CookiePoisoning.PhishingForCookies.ContainsKey("admin");
        *
        * or when the firewall knows the user is a bot, but not a search engine
            e.AllowRaiseIncident = user.UserType.HasFlag(UserTypes.IsBot) && !user.UserType.HasFlag(UserTypes.IsSearchEngine);
        */
        e.AllowRaiseIncident = true;

        var user = e.Page.User.AsFirewallUser();

        //what ever the firewall detected the user was, add the fact that the user is malicious
        user.UserType |= UserTypes.IsMalicious;



        //you can do this in the logger but as we are going to block the response making it a ms slower will not "harm user experience"
        var InterNetProviderAbuseContact = e.Page.GetAbuseContact();
        var ipAddressFromCountry = Walter.BOM.Geo.GeoLocationMapping.GetCountryName(e.Page.Country ?? InterNetProviderAbuseContact.Country);

        //loop over all poisoned cookies and log them
        foreach (var cookie in e.PoisonedCookies)
        {
            if (e.Page.User.IsSearchEngine == SearchEngine.NotSure)
            {
                _logger.LogWarning("Cookie {name} was poisoned with {value} when {original} was send to by {IP} via {ISP_Name} contact {ISP_Email} in {country}"
                    , cookie.Name
                    , cookie.PoisonedValue
                    , cookie.OriginalValue
                    , user.IPAddress
                    , InterNetProviderAbuseContact.Name
                    , InterNetProviderAbuseContact.EMail
                    , ipAddressFromCountry
                    );
            }
            else
            {
                _logger.LogWarning("Cookie {name} was poisoned with {value} when {original} was send to site by search engine {searchEngine}"
                    , cookie.Name
                    , cookie.PoisonedValue
                    , cookie.OriginalValue
                    , e.Page.User.IsSearchEngine
                    );
            }

        }
    }