2.24 邊界,邊界,還是邊界

以前玩一款新出的遊戲,找到了一個充值漏洞,在充值會員的時候在充值數量輸入框中先輸入-999999,提交後再輸入正數的充值數,就可以不用花錢而得到金幣,那段時間在遊戲裏真是揮金如土,什麼神獸神兵,武功祕籍,隨便買,從而虐遍全服~~雖然很不幸,不到半個月就被封號……


來模擬下單業務邏輯:

<pre name="code" class="java">public class Client {
	public final static int LIMIT = 2000;// 可擁有產品的最大數量

	public static void main(String[] args) {
		int cur = 1000;// 目前擁有產品數量
		Scanner input = new Scanner(System.in);
		System.out.print("輸入預訂數量:");
		while (input.hasNextInt()) {
			int order = input.nextInt();
			if (order > 0 && order + cur <= LIMIT) {
				System.out.println("你已經成功預訂" + (cur + order) + "個產品");
			} else {
				System.out.println("超過限額,預訂失敗!");
			}
		}
	}
}

這是一個很簡單的訂單處理程序,看似沒有問題,但是請看輸出結果:
輸入預訂數量:800
你已經成功預訂1800個產品
2147483647
你已經成功預訂-2147482649個產品
這個2147483647是不是很眼熟?沒錯,這是int類型的最大值,因爲這個值再加上1000的時候超出了int類型的範圍,所以結果反而變成了負的。一句話歸結其原因:數字越界使校驗條件失效

所以在單元測試中,有一項測試叫做邊界測試(也有叫做臨界測試),如果一個方法接受的是int類型,那麼以下三個值是必測的:0、正最大、負最小。如果這三個值都沒問題,這個方法纔是比較安全可靠的。

就算你再Web界面做出了嚴格嚴謹的校驗,但其實也只能防普通用戶(這裏普通用戶指不懂HTML、不懂HTTP、不懂Java的簡單使用者),而對於高手,這些校驗基本上就是擺設,通過對數據進行攔截分析,再寫個模擬器進行發送,一切的前段校驗就都變成了浮雲!!

所以,必要的數據驗證要放在服務端進行


來源:《編寫高質量代碼:改善Java程序的151個建議》

發佈了63 篇原創文章 · 獲贊 5 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章