在烏雲上看到的,一個線程並發漏洞,有人願給講講原理和修複方案嗎?
http://www.wooyun.org/bugs/wooyun-2010-0102881
而是在發送的請求讀資料時未及時鎖住資料資訊導致可多線程並發多次利用優惠劵。
這個BUG如何理解呢?難道是開多個瀏覽器同時使用優惠券嗎?如何堵住BUG呢?
回複內容:
在烏雲上看到的,一個線程並發漏洞,有人願給講講原理和修複方案嗎?
http://www.wooyun.org/bugs/wooyun-2010-0102881
而是在發送的請求讀資料時未及時鎖住資料資訊導致可多線程並發多次利用優惠劵。
這個BUG如何理解呢?難道是開多個瀏覽器同時使用優惠券嗎?如何堵住BUG呢?
這個bug是沒及時修改優惠券狀態所致的。
第二次請求的時候,第一次請求還沒來得及把優惠券的狀態改成”已使用“,導致第二次也可以使用優惠券。
這是一個邏輯不嚴謹導致的bug, 跟線程互斥沒什麼關係。
防止這個bug的方法,就是保證及時修改優惠券的狀態。
關於如何製造這個bug的方法很多, 很多語言都有多線程\多進程功能, 開起來同時請求就行了。
甚至題主說的用多開瀏覽器請求也是可以的。
跟你簡單的說吧,你現在去買東西,掏錢才給你開門,你掏了錢,門開了,忽然你的東西掉了(不要問怎麼掉了),你低下頭去撿東西(店門沒關,線程沒鎖),這時候B君進來拿走了你要的東西,此時你抬頭,也詢問你的東西,店家還是乖乖給了你...而且這段門敞開的時間,多個線程都可能搶佔,僅僅只有一個線程觸發了交易完成,店家才知道,完成了交易,這時候,剩下的線程才進不來(具體那個線程觸發這個關門操作都是隨機的,跟電腦當時的狀態都有關,因為線程執行是不斷切換的)關閉店門,在這段時間內ABCDE君都可能免費拿到東西.
一般支付流程如下:
讀取餘額
判斷是否大於0
餘額減一
寫回餘額
當兩個線程同時執行,假設餘額為1,兩個線程並發執行(假設第二個線程落後於第一個),第二個線程在第一個線程將寫回餘額之前讀取了餘額,那麼線程二也會判斷成功,照樣會執行購買成功的流程。
設計的好一點兒的情況是,結果資料庫裡的結果是-1,壞一點兒的情況是資料庫裡的的結果是0 (因為第二個線程讀取的是1,減一之後寫回所以是0).
解決方案就是加鎖,線上程一讀取餘額之前加鎖,讓要讀取餘額的線程二掛起等待線程一寫回餘額再讀取。
所有資料庫都可能存在這樣的情況,有人用來取現的。http://www.wooyun.org/bugs/wooyun-2015-099622