我将数据保存在cookie中,以便为下次登录时的用户进行身份验证(请记住我的选项)。这些数据经过加密和散列。
但问题出在这里:
任何人都可以拿这个cookie并把它放在另一台机器上,它会起作用。
我听说这叫做cookie中毒
我如何克服这个问题?
答案 0 :(得分:4)
将计算机的IP地址和/或主机名存储在cookie(哈希值)以及当前的方案中,并对其进行验证。
答案 1 :(得分:3)
你真的无法阻止它,但你可以采取一些措施来使它变得更难,从而减少吸引力
要求用户在整个会话中使用https(443)。这可以防止任何中间人攻击嗅探cookie
一次只允许一个会话处于活动状态。第二个会话出现后,第一个会话无效。
要求用户在更改密码时进行提供旧密码(编辑:或电子邮件地址或其他可能导致帐户在登录后被盗的内容);这样可以防止有人劫持帐户并轻松更改密码。
会话cookie的生命周期非常有限 - 可能需要几个小时。
话虽如此,由于您打开了系统门,您可能希望确保不存储任何易于用户阅读的敏感信息。因此,例如,如果系统中有信用卡或SSN,请不要将其显示给用户。
答案 2 :(得分:2)
您所描述的威胁是攻击者会窃取用户的Cookie并使用它来访问该用户的会话。防止这种情况的一种方法是存储IP地址或主机名,如Daniel A White提到的那样,但如果不可能,则没有100%安全的方式来协商这一点。
以下是其他一些可以抵御此类攻击的选项:
答案 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
);
}
}
}