適用對象:搜尋或類似功能會呼叫外部 API 的網站營運者。本文概括了本站營運者經營的一個網站實際發生的事件。文中不提及任何網站、外部服務,也不提供確切的限制值或日期,且不涵蓋攻擊手法。
發生了什麼事
在本站營運者經營的網站上,搜尋功能每次搜尋都會呼叫外部 API。幾天內,搜尋流量升至約正常的 20 倍。外部 API 有並行上限,絕大多數搜尋(超過 90%)都回傳 503。
最初的假設是每 IP 限制(每分鐘 N 次)可以控制它。這個假設是錯的。
幾天內搜尋流量約增加 20 倍
外部 API 的並行上限被打滿,幾乎所有搜尋都回傳 503。當時看起來只是錯誤變多。
最初假設:每 IP 限制可以控制它(錯誤)
以每分鐘每 IP 計數,可以抓到少數 IP 發出大量呼叫的情況。但這不是這類流量。
測量結果
某一天約 60,000 次搜尋來自約 60,000 個不同的 IP,每個 IP 約一次請求。模式看起來像住宅代理網路。使用者代理是一般瀏覽器,Referer 是網站本身,查詢內容是真實的商品名稱。價格蒐集可能是其目的。
外部 API 的每日配額在當天較早就用完
機器人的搜尋很快耗盡配額,一般訪客在大部分時間都無法搜尋。
為何看起來不像真正的問題
配額受到保護,因此外部 API 看起來正常,網站只看到錯誤變多。保護配額與讓使用者能使用功能,結果是兩回事。
預期情況:少數 IP 發出大量呼叫
觸及每 IP 限制 → 已阻擋 ✓
實際情況:約 60,000 個 IP,每個一次請求
沒有任何 IP 達到限制 → 只有外部 API 的配額被耗盡
= 只要計數單位是 IP,這種模式就是隱形的
上游配額受保護,不代表使用者能使用功能
任何保護外部 API 配額或並行數的機制,都是為了避免該 API 故障。機制運作時,上游不會顯示錯誤。代價則落在失去配額的一方:你自己的訪客。
正因為保護機制正常運作,問題才難以察覺。應監控的是真實訪客搜尋時取得的成功率。
如何阻止
未能阻止的設計
任何人的任何搜尋請求都會呼叫外部 API。唯一的限制是每 IP 計數。分散式流量讓每個 IP 的計數都很低,因此永遠不會觸發限制。
有效的設計
只有帶有網站自身頁面發出的簽章權杖(Cookie)的搜尋才會呼叫外部 API。沒有權杖時,回傳輕量頁面或 403。此外,全域及每個權杖都設定每小時上限。
- 簽章權杖
- 由網站自身頁面發出的權杖,成為呼叫外部 API 的條件。沒有權杖時,回傳輕量頁面或 403
- 保護彙整資料
- 沒有權杖的搜尋被排除在熱門搜尋排名之外,該排名先前已被機器人的查詢灌水
- 每小時上限
- 同時設定全域上限與每個權杖的上限
上線後,503 立即降為零。現在每天約 100,000 次沒有權杖的請求會收到 403,正常搜尋則可順利完成。
經驗教訓
- 每 IP 限制無法對付分散式機器人。每個 IP 只送出一次請求,無論限制設得多低都擋不住。
- 上游配額受保護,並不等於使用者能使用功能。保護機制可能掩蓋問題。
- 排名等彙整資料會被污染。除了保護外部 API,也應限制哪些資料能輸入這些彙整。
你可以怎麼做
以下順序是本站自身的建議,並非引用來源的聲明。
在任何高成本步驟之前,先檢查網站發出的權杖
在會消耗成本或配額的步驟(例如呼叫外部 API)之前,先檢查是否帶有自家頁面發出的簽章權杖。為權杖設定到期時間,並在伺服器端驗證。若缺少權杖,就不要繼續,應回傳輕量頁面或 403。
讓沒有權杖的流量遠離彙整資料
熱門搜尋、查詢統計與推薦內容只根據帶有權杖的搜尋建立,避免機器人的查詢滲入網站所顯示的內容。
設定全域與每個權杖的上限
使用每小時全域上限與每個權杖的上限,而非每 IP 計數。全域上限是最後的防線,用來防止外部 API 的配額被耗盡。
加入結果快取與排隊
重複的查詢改由快取提供,不再重複呼叫外部 API;忙碌時則將請求排入佇列。當某項措施被繞過時,配額較不會瞬間消失。
監控訪客看到的成功率
記錄真實訪客搜尋成功的比例,而不只是外部 API 的錯誤率,並在比例下降時發出警示。這就是組織資安基準中所說的「能察覺異常」的狀態。
權杖不是身分驗證,它會提高攻擊者的成本
權杖不是身分驗證。權杖能做的,是阻止單純猛打搜尋網址的流量;它並不是完整的防禦。
因此它需要與快取、排隊及每個權杖的上限搭配使用。本站的看法是,如果機器人每次都取得新權杖,每個權杖的上限就沒有幫助,所以務必搭配全域上限與快取。如同速率限制與濫用控制中所述,本站的觀點是讓濫用的成本高到不值得,而不是把其成功率壓到零。
資料來源(原始)
- OWASP API Security Top 10 2023,「API4:2023 Unrestricted Resource Consumption」— api-security.owasp.org(限制客戶端在一段時間內與 API 互動的頻率;為外部服務設定支出上限)
- OWASP Automated Threats,「OAT-011 Scraping」— owasp.github.io(將爬取定義為收集內容或資料以供他處使用,例如價格操縱;無需驗證的資料可能成為目標)
延伸閱讀
- 設計:速率限制與濫用控制:設計能阻止暴力破解與失控成本的限制
- 前置知識:X-Forwarded-For 偽造與受信任的代理(依 IP 計數的基礎)
- 營運:組織資安基準(如何察覺異常)