幾週前,我們在 Suga 上注意到一些奇怪的現象。新用戶不斷註冊,但卻什麼都不做,他們沒有建立組織、專案或部署,只是留下一個閒置的帳戶。大多數新用戶都會很快地與產品互動,我們會監控活動統計數據以了解阻礙因素,因此即使是少量完全不活躍的帳戶激增也顯得格外突出。
接著我們查看了新用戶的名字,發現它們是像 PfVQXvYTXjwSbEeJBjXYy 和 xXzMafkbPLjOaGgDaOGZjLx 這樣的條目。
我們檢查了 Resend(我們的電子郵件服務),可以看到歡迎電子郵件已發送並送達這些帳戶。它們是真實的電子郵件地址,但名稱卻是亂碼……有些東西不對勁。
進行這些攻擊的人正在竊取金錢,並冒充真實人物或企業。網路上任何允許您輸入任何電子郵件地址而無需驗證的註冊表單,都是他們可以利用的工具。
攻擊始於 3 月 12 日,當時只有一次異常的註冊,然後在接下來的兩天裡,我們每天看到 2-3 次,這個數量足夠低,可以被視為雜訊。老實說,我們最初的想法是有人在對我們的服務進行滲透測試。這很常見,我們在其他產品上也有過經驗,而且當有負責任的披露時,我們很欣賞,所以當時並沒有敲響警鐘。
到了 3 月 14 日,我們發現有 6 個符合模式的註冊,並且我們在 PostHog 中注意到了一些其他事情。忘記密碼頁面出現了異常高的頁面瀏覽量和互動。這些活動的組合足以讓我們仔細檢查。
三封他們從未要求過的電子郵件,來自一個他們可能從未聽說過的產品。我們可能是當時數百個同時受到攻擊的網站之一。
機器人還在用隨機的電子郵件地址攻擊忘記密碼頁面,據推測是試圖觸發已經是我們用戶的受害者的重設電子郵件。
我們詳細審查了一個會話,其打字行為很有趣。機器人在表單欄位中輸入值時速度非常慢,一次一個字元,每次擊鍵之間間隔長達一秒。間隔具有隨機性,但隨機性過於明顯。人類打字是分段進行的,大多數人會快速輸入幾個字元,然後暫停,再繼續輸入。這種情況是平坦的延遲分佈,試圖看起來像人類但失敗了。頁面導航之間的計時也具有相同的隨機性,但卻是均勻的。有足夠的變化來躲避簡單的機器人檢測,但不足以真正通過真實人物的標準。
請求來自世界各地(印度、巴西、羅馬尼亞、美國、越南、土耳其),這並不罕見,直到你將其與典型流量進行比較。我們的真實用戶通常從特定國家導航,並且與該國的白天時間有合理的相關性。機器人流量與國家和一天中的時間之間沒有任何相關性,這種不匹配正是我們注意到的地方。
速率限制在這裡毫無作用,因為你無法真正對每小時一次的請求進行速率限制。這種攻擊的重點就是保持在閾值之下,這也是我認為這種攻擊類型如此有趣的原因之一。
想像一下醒來時收到 200 多封來自你從未聽說過的服務的電子郵件,你開始刪除它們,但它們卻不斷湧來。在那堆垃圾郵件中,有一個重要的通知,比如有人更改了你的銀行電子郵件地址、重設了你的密碼,或者以你的名義訂購了新的信用卡。
如果你的註冊表單將電子郵件發送到未經驗證的地址,你的表單就是其中的一部分。由於損害落在受害者身上,而不是網站所有者身上,我懷疑大多數人會將其視為低優先級的修復,這是錯誤的。它污染了你的用戶數據,並使你的服務成為騷擾真實人物的幫兇。
我們的第一步是收緊前端託管提供商防火牆上的機器人檢測。這將流量減少了大約一半,但並未完全消除。配置也很棘手,因為我們有合法的非瀏覽器流量(webhook、服務對服務調用)正在訪問我們的 API,這些流量需要繼續工作。
我們讓它運行了大約 6 個小時。在此期間,又有兩個註冊溜了進來(一個在 5 小時標記,另一個在 6 小時)。機器人正在繞過驗證步驟,所以我們需要更好的方法。
Cloudflare Turnstile 是解決方案,它是一種 CAPTCHA 的替代品,不會要求用戶解決謎題。它會在後台分析瀏覽器信號,並可以在發現異常時配置為僅顯示可見的挑戰。您可以將其設置為對真實用戶隱形。
我們使用 Better Auth 進行身份驗證,它內建了支援 Turnstile 的 CAPTCHA 外掛程式。這使得實施變得非常簡單,只需在伺服器端添加外掛程式,將 Turnstile 組件放在註冊、登入和忘記密碼等頁面上,使用 @marsidev/react-turnstile,然後通過標頭將令牌傳遞到伺服器。提交按鈕會一直禁用,直到 Turnstile 提供有效的令牌。
部署 Turnstile 後,機器人註冊停止了,所以我想特別感謝 Better Auth 和 Cloudflare Turnstile。這種組合使問題在當天就得到了解決。如果您的身份驗證解決方案不支援內建的 CAPTCHA,Turnstile 的 API 仍然可以輕鬆地直接集成,但內建功能為我們節省了時間。
即使有了 Turnstile,我們也希望限制將來再次發生此類事件的損害。我們更新了電子郵件服務代碼,以便用戶在點擊連結並證明他們擁有該地址之前,只會收到我們的一封電子郵件(驗證電子郵件)。沒有歡迎電子郵件,沒有產品更新,在驗證之前什麼都沒有。我們一開始就應該這樣做,這是我後悔的錯誤。
如果機器人使用他人的電子郵件創建帳戶,受害者會收到一封電子郵件,如果他們忽略了,事情就結束了。歡迎電子郵件和之後的所有內容都只會在用戶驗證後才會發送。
(對於通過 Google 或 GitHub 進行的社交身份驗證註冊,我們會立即發送歡迎電子郵件,因為這些提供商已經驗證了他們的電子郵件地址。)
我們本可以對每小時 1-2 次的註冊置之不理,因為對我們來說,業務影響基本上為零。但那些是真實人物的電子郵件地址,而我們的服務卻被用來對付他們。
我想向那些電子郵件地址被使用的受害者道歉,但聯繫他們只會給他們已經不堪重負的收件箱增加一封不必要的電子郵件。我們能做的最好的就是阻止它發生,並確保我們無法再以這種方式被利用。
我們還添加了更好的報告功能,以便下次能更快地發現類似的模式。總體而言,我認為我們的回應是合理且相當迅速的,但我們一開始就應該有這些緩解措施,經驗已學到。