2010-06-25 74 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

相關問題