2010-06-25 75 views
2

我有密码页面,当有人输入不正确的密码,我想简单地通过具有为什么lock(this)thread.sleep不适用于ASP.NET线程?

bool isGoodPassword = (password == expected_password); 

lock (this) 
{ 
    if (!isGoodPassword) 
      Thread.Sleep(2000); 
} 

我希望这将让所有正确的密码,而不会停止衬托出蛮力攻击,但如果一个用户进入来自不同用户的另一个成功密码也会被阻止。但是,锁在跨ASP.NET线程似乎不lock。没有意义。

回答

16

那么,你没有显示“this”是什么,但是如果你在一个页面的上下文中......每个请求都将获得它自己的页面实例,不是吗?否则,他们首先会有什么不同的密码?您将拥有多个线程,每个线程都锁定在一个单独的对象上。

在许多方面,这是一个事情:你不希望真正的用户受到攻击者的影响。另一方面,这意味着攻击者只需要平行进行多次尝试,以便有效地忽略你阻止他的企图。正如其他答案所述,你可以使用通过使用一个单一的对象 - 但请不要。不要忘记,IIS不会创建新的线程:这种方法可以让单个攻击者使整个应用程序无法用于所有用户,不仅仅用于身份验证,甚至不需要有有效的密码。

相反,您可能希望考虑记录认证失败的IP地址,并限制您愿意以这种方式处理的请求数量。 (不可否认,如果某些用户与攻击者位于同一个代理之后,可能会遇到问题,但这不太可能。)这不会阻止分布式攻击,但这是一个好的开始。

+0

感谢您的回答乔恩。有几种方法可以启动我的应用程序,我正在寻找一种快速便宜的解决方案。没有想到多个实例,并认为你在那里发现。 – 2010-06-26 07:38:43

2

如果你真的想访问的页面块中的所有用户,如果弄乱了他的密码之一,你总是可以做

bool isGoodPassword = (password == expected_password); 

lock (this.GetType()) 
{ 
    if (!isGoodPassword) 
      Thread.Sleep(2000); 
} 

为你写它,这只会减慢刷新当前请求,它不会阻止多连接攻击。

此外,比较密码意味着你知道用户密码,蚂蚁总是不好的做法。更好的方法是保留用户通行证的(腌制)散列,并将其与输入的散列进行比较。 另外,您可能希望采用累进延迟(第1个错误 - 第1个等待时间,第2个错误 - 第2个,第3个 - 第4个等等)

2

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请求,并阻止任何其发送一定量超过一定的时间。

2

我的两分钱:我找了一个不同的方法。我不相信软件解决方案是防止拒绝攻击的正确场所。最终,这个解决方案将失败。 IIS需要花费时间处理代码,直到达到锁码。锁码不阻止请求。它只允许一次通过。它有效地作为一个队列。

就这样说,尝试使用一个静态变量。

private static readonly object _lock = new object(); 

... 

lock (_lock) 
{ 
    if (!isGoodPassword) 
      Thread.Sleep(2000); 
} 
+0

我认为这个问题与我认为你所假设的拒绝服务攻击有任何关系。这与减慢用户能够快速猜测许多不同的密码有关。但是,是的,我们都同意,尝试解决方案对此非常糟糕。 – Jaxidian 2010-06-25 21:05:52

+0

这不是一个很好的地方来发现拒绝攻击,但它可能是一个合理的地方来抓字典攻击。 我不认为你想要这样绑定一个线程。它实际上会使拒绝攻击变得更容易。 – 2010-06-25 21:07:53

+1

只读是不一样的静态。 – 2010-06-25 21:11:16

相关问题