票務系統如何工作
票務系統(您在節日期間看到的票證系統)的工作方式如下:當用戶付款時,會在數據庫中添加一行,列名為 is_scanned
,其默認值設置為false。
節日期間,守衛一使用設備掃描條形碼(包含ID和唯一的哈希),就會發送請求到數據庫以檢查:
- 與ID和哈希匹配的用戶是否已經付款,並且
- 列
is_scanned
的值是否仍然設置為false
。 ol> - 如果入口沒有足夠的延遲,則會使入口處的一切變慢
- 無效。因為如果數據庫花費50毫秒將
is_scanned
從false
更新為true
,則唯一的解決方案是將其延遲最小間隔每次50毫秒。 ol>
如果同時滿足兩個條件,則會將值 is_scanned
設置為 true
, 以防止其他人復制票證/條形碼進入。
漏洞問題
這裡的問題是請求方發送請求到發送請求之間的時間掃描設備,並且值 is_scanned
從 false
切換為 true
。
請考慮以下場景里約:愛麗絲(Alice)擁有一張有效的機票,並已付款,但隨後她讓夏娃(Eve)複製條形碼,並將假機票上的可見名稱從愛麗絲(Alice)更改為夏娃(Eve)。所以現在我們有兩張票。一個有效和一個欺詐,但都具有相同的條形碼,唯一的區別是名稱。
如果進入節日的愛麗絲和夏娃的票被完全同時掃描怎麼辦? ?票務系統不會及時將 is_scanned
切換為 true
,以確保Eve不能輸入與Alice相同的條形碼。導致檢票員(有效票證和欺詐票證)對守衛都顯示為“有效”。運氣,雖然在理論上有可能...在實際情況下,這可能會失敗。
但是,在理論上我們又如何打敗這種利用?
我已經使用以下方法考慮了此漏洞:掃描條形碼時,我不僅顯示票證是否有效(滿足前面所述的條件),還顯示 數據庫中的名稱。如果名稱與故障單上的名稱不匹配,我們就知道故障單是通過某種方式操縱的。另外,如果掃描設備上顯示的名稱與ID上的名稱不匹配(每個人都必須出示該名稱以證明年齡),則也不允許輸入該名稱。
唯一的方法是繞過此解決方案的是身份欺詐,這當然不屬於票務系統的責任。
Delay
從理論上講,解決此問題的另一種方法是添加一個對數據庫/驗證API的每個請求之間的隨機延遲時間。這樣,沒人會同時掃描他們的票...因為每次的驗證時間都被延遲了隨機的毫秒數。
我不喜歡這個,因為它:
其他解決方案?
您認為還有哪些其他解決方案可以解決此漏洞?