[英]Why does lock(this) thread.sleep not work with ASP.NET threading?
我有一个密码页面,当有人输入错误的密码时,我想简单地挫败蛮力攻击
bool isGoodPassword = (password == expected_password);
lock (this)
{
if (!isGoodPassword)
Thread.Sleep(2000);
}
我希望这将允许所有正确的密码而不会停止,但如果一个用户输入错误的密码,另一个用户的另一个成功密码也将被阻止。 但是,锁似乎并未lock
ASP.NET线程。 没有意义。
好吧,你没有显示“这个”是什么,但是如果你在一个页面的上下文中......每个请求都会得到它自己的页面实例,不是吗? 否则他们首先会有不同的密码? 你将有几个线程,每个线程都锁定一个单独的对象。
在许多方面,这是一件好事 :你不希望真正的用户被攻击者affeted做。 另一方面,这意味着攻击者只需要并行进行多次尝试,以便有效地忽略你欺骗他的企图。 正如其他答案所述,您可以通过使用单个对象来解决这个问题 - 但请不要。 不要忘记IIS不会无限制地创建新线程:这种方法会让单个攻击者让整个应用程序无法用于所有用户,而不仅仅是用于身份验证,而是整个应用程序......他们甚至都不会需要有一个有效的密码。
相反,您可能希望考虑记录认证失败的IP地址,并限制您愿意以这种方式处理的请求数量。 (不可否认,如果某些用户与攻击者在同一个代理服务器后面,可能会遇到问题,但不太可能。)这不会阻止分布式攻击,但这是一个良好的开端。
如果你真的,真的想阻止所有用户访问该页面,如果其中一个搞砸了他的密码,你可以随时做
bool isGoodPassword = (password == expected_password);
lock (this.GetType())
{
if (!isGoodPassword)
Thread.Sleep(2000);
}
正如你所写的,这只会减慢当前请求的刷新速度,它不会阻止多连接攻击。
此外,比较密码意味着你知道用户密码,蚂蚁总是一个坏习惯。 更好的方法是保留用户传递的(盐渍)哈希值,并将其与输入的哈希值进行比较。 此外,您可能希望使用渐进式延迟(第一个错误 - 1秒等待时间,第二个错误 - 2秒,第3个 - 4等等)
ASP.NET在单独的线程上运行每个请求。 如果要锁定请求,可以使用静态对象:
public class LogOn : Page
{
private static object _delaySync = new object();
private void Authenticate()
{
lock(_delaySync)
{
if(password != expected_password)
{
Thread.Sleep(2000);
}
}
}
}
但是,通过IP跟踪请求并阻止在一定时间内发送特定音量的任何内容可能更有意义。
我的两分钱:我想找一个不同的方法。 我不相信软件解决方案是防止拒绝攻击的正确位置。 最终,此解决方案将失败。 IIS将代码处理到达锁定代码的时间需要一些时间。 锁码不会阻止请求。 它只允许一次通过。 实际上它充当队列。
话虽如此,尝试使用静态变量。
private static readonly object _lock = new object();
...
lock (_lock)
{
if (!isGoodPassword)
Thread.Sleep(2000);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.