知識庫 / Spring / Spring Security RSS 訂閱

阻止用户名枚舉攻擊與Spring Security

Spring Security
HongKong
5
01:28 PM · Dec 06 ,2025

1. 概述

本教程將描述枚舉攻擊的一般原理。更具體地説,我們將探討針對Web應用程序的用户名枚舉攻擊。最重要的是,我們將探索通過Spring Security處理這些攻擊的選項。

2. 解釋枚舉攻擊

枚舉(Enumeration)技術上是指對一個集合中的所有項目進行完整且有序的列舉。 儘管這個定義主要應用於數學領域,但其本質使其成為一種強大的黑客工具。 枚舉經常會暴露可用於利用的攻擊向量。 在這個語境下,它通常被稱為資源枚舉。

資源枚舉,正如其名稱所暗示的,是一種從任何主機收集資源清單的方法。 這些資源可以是任何有價值的東西,包括用户名、服務或頁面。 這些資源可能會暴露主機中的潛在漏洞。

現在,存在多種可能的方式,既有被探索的,也有未被探索的,來利用這些漏洞。

3. 針對Web應用程序的流行枚舉攻擊

在Web應用程序中,最常用的枚舉攻擊之一是用户名枚舉攻擊。 這本質上利用了Web應用程序的任何顯式或隱式功能來收集有效的用户名。攻擊者可能會使用流行的用户名選項來攻擊Web應用程序。

那麼,Web應用程序中的哪些功能可能表明用户名是否有效? 誠然,它可能多種多樣。 例如,它可能是一個設計好的註冊頁面,讓用户知道用户名已被佔用。

或者,它可能像事實本身一樣隱蔽,即使用有效用户名進行登錄嘗試所需的時間與使用無效用户名進行嘗試所需的時間大相徑庭。

4. 模擬用户名枚舉攻擊的設置

我們將使用一個簡單的基於 Spring Boot 和 Spring Security 的用户 Web 應用程序來演示這些攻擊向量。該 Web 應用程序將具有一個最小的功能集,以支持演示。關於如何設置此類應用程序的詳細討論,請參考之前的教程。

Web 應用程序的常見功能可能會泄露信息,這些信息可用於發起枚舉攻擊。讓我們來詳細瞭解一下。

4.1. 用户註冊

用户註冊需要一個唯一的用户名,電子郵件地址通常被選擇是因為其簡潔性。如果選擇一個已存在的電子郵件地址,應用程序應告知用户。

考慮到電子郵件列表並非難以獲取,這可能導致用户名枚舉攻擊,從而在應用程序中提取有效的用户名。

4.2. 用户登錄

當嘗試登錄應用程序時,我們需要提供用户名和密碼。如果提供的用户名不存在,應用程序可能會將此信息返回給我們:

正如之前所述,這對於用户名枚舉攻擊來説非常簡單。

4.3. 重置密碼

重置密碼通常通過向用户郵箱發送密碼重置鏈接來實現。現在,再次需要我們提供用户名或郵箱:

如果該用户名或郵箱在應用程序中不存在,應用程序會告知用户,從而導致我們之前所見的那種漏洞。

5. 防範用户名枚舉攻擊

有多種方法可以防止用户名枚舉攻擊。其中許多可以通過在Web應用程序中對用户消息等功能進行簡單的調整來實現。

此外,隨着時間的推移,Spring Security已經成熟到足以支持處理許多此類攻擊向量。它內置了功能和擴展點,可用於創建自定義安全措施。我們將探討這些技術。

讓我們回顧一下可用於防止此類攻擊的流行選項。請注意,並非所有這些解決方案都適用於Web應用程序的每個部分,甚至可能無法實現。我們將隨着討論的進行更詳細地討論這些問題。

5.1. 調整消息內容

首先,我們必須排除任何意外透露過多信息的可能性。這在註冊過程中比較困難,但在登錄和重置密碼頁面則相對簡單。

例如,我們可以輕鬆地使登錄頁面的消息內容更加抽象:

我們也可以對密碼重置頁面的消息內容進行類似的調整。

5.2. 引入 CAPTCHA

雖然對消息進行調整在某些頁面上效果良好,但在像註冊頁面這樣的頁面上,這樣做會比較困難。在這種情況下,我們可以使用另一種工具,即 CAPTCHA。

現在,在此階段,值得注意的是,任何枚舉攻擊很可能由大量可能性導致,因此,檢測人類或機器人存在可以幫助我們防止攻擊。CAPTCHA 是一種流行的實現這一目標的方式。

在 Web 應用程序中實施或集成 CAPTCHA 服務有多種可能的方法。其中一種服務是 Google 的 reCAPTCHA,可以輕鬆地集成到註冊頁面上。

5.3. 速率限制

雖然 CAPTCHA 在一定程度上發揮作用,但它也會增加延遲,更重要的是,會給合法用户帶來不便。這對於經常使用頁面,如登錄頁面,尤其相關。

一種可以幫助防止在經常使用頁面,如登錄頁面上機器人攻擊的技術是速率限制。 速率限制是指在達到一定閾值後,阻止對資源的連續嘗試。

例如,我們可以阻止來自特定 IP 地址的請求,在登錄嘗試失敗三次後,隔一天:

Spring Security 使此方法尤其方便。

我們首先定義監聽器 AuthenticationFailureBadCredentialsEvent,該監聽器將統計源 IP 地址的失敗嘗試次數。當攻擊者嘗試進行暴力破解攻擊時,它將在 LoginAttemptService 中設置的閾值後阻止,並且無法重置計數器 24 小時。一旦超過設置的閾值,後續請求將被 UserDetailsService 阻止。我們還會在每次失敗時檢查用户是否被阻止,並生成正確的錯誤消息。

有關此方法的詳細討論可以在另一教程中找到。

5.4. 地理限制

此外,在用户註冊時,我們還可以通過用户的國家來捕獲其位置信息。 這可以用於驗證來自不同位置的登錄嘗試。 如果我們檢測到異常位置,則可以採取適當的措施:

  • 啓用選擇性的驗證碼
  • 強制實施多因素身份驗證(作為多因素身份驗證的一部分)
  • 要求用户安全地驗證其位置
  • 在連續請求中臨時阻止用户

再次指出,Spring Security 通過其擴展點,使得在 AuthenticationProvider 中插入自定義位置驗證服務成為可能。 這種類型的服務在之前的教程中已經詳細描述過。

5.5. 多因素身份驗證

最後,我們應該注意到基於密碼的身份驗證通常是第一步,在大多數情況下是唯一一步。但是,應用程序採用多因素身份驗證機制以提高安全性並不罕見,尤其適用於在線銀行等敏感應用程序。

當涉及到多因素身份驗證時,有多種可能因素:

  • 知識因素: 指的是用户知道的內容,例如PIN碼。
  • 擁有因素: 指的是用户擁有的東西,例如令牌或智能手機。
  • 內在因素: 指的是用户天生具備的東西,例如指紋。

Spring Security 在這裏也提供了便利,因為它允許我們插入自定義 AuthenticationProvider。 Google Authenticator 應用程序是實施附加擁有因素的流行選擇。 這允許用户在智能手機上的應用程序中生成臨時的令牌,並將其用於任何應用程序的身份驗證。 顯然,這需要在應用程序中事先設置用户,要麼是在註冊期間,要麼是在稍後。

將 Google Authenticator 集成到 Spring Security 應用程序中,在之前的教程中已經得到了充分的覆蓋。

更重要的是,像多因素身份驗證這樣的解決方案只有在應用程序確實需要它時才適用。 因此,我們不應該主要將其用於防止枚舉攻擊。

5.6. 請求處理延遲

當處理諸如登錄請求這樣的請求時,通常首先要做的事情就是檢查用户名是否存在。如果用户名不存在,請求會立即返回帶有錯誤信息。相反,如果用户名有效,請求會涉及許多後續步驟,例如密碼匹配和角色驗證。自然,這兩個情況的響應時間可能會有所不同。

即使我們抽象了錯誤消息,以隱藏用户名是否有效的事實,但顯著的差異在處理時間上仍然可能引起攻擊者的注意。

為了解決這個問題,可以添加強制延遲,以消除處理時間的差異。然而,由於這並不是一個可以確定發生的難題,因此我們只有在必要時才應採用此解決方案。

6. 總結

雖然我們已經涵蓋了在用户名枚舉攻擊中使用的各種技巧,但自然會有人問,應該在什麼情況下使用它們?顯然,沒有一個適用於所有情況的答案,這主要取決於應用程序的類型和其要求。

一些事項,例如向用户發送的消息,必須儘可能減少信息泄露。此外,限制對諸如登錄等資源的多次失敗嘗試也是明智之舉。

然而,我們應該只使用任何額外的措施,如果要求確實需要的話。我們還應該理性地權衡這些措施對可用性的影響。

更重要的是,我們應該意識到,可以將這些措施的不同組合應用於不同的資源,從而有選擇地對其進行安全保護。

7. 結論

在本教程中,我們討論了枚舉攻擊——特別是用户名枚舉攻擊。我們通過以一個簡單的 Spring Boot 應用和 Spring Security 為例,來分析這些問題。

我們探討了解決用户名枚舉攻擊的多種方法。

最後,我們討論了這些措施在應用安全中的適用性。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.