SQL injection 幾種無效的防護程式範例迷思
這篇文章主要用兩個常見的範例說明無效的編碼防護方式
許多人常認為只要將特殊服務去除或是使用 Store procedure
就自然不會受到 SQL injection的攻擊
筆者舉兩個例子說明這樣的迷思與錯誤的觀念
迷思一: 過濾特殊字元
許多開發人員認為只要將 SQL 特殊符號去除就可以避免SQL injection
常見的簡單方式包含將 ‘ 變成 ”
儘管這樣的方式可以避免大部分的 SQL injection 但是還是會有遺漏的風險
讓我們來看一個例子, 這個例子中productName已經將輸入的字串將單引號 ‘ 變成雙引號” 避免 SQL injection 的攻擊
儘管這樣可以解決大部分的 SQL injection 攻擊, 這樣的方式到底會有什麼問題呢?
[pastacode lang=”java” message=”” highlight=”” provider=”manual” manual=”int%20price%20%3D%20…%3B%20%2F%2F%20price%20%0A%0Astring%20productName%20%3D%20…%3B%20%2F%2F%20product%20Name%0AproductName%20%3D%20productName.Replace(%22’%22%2C%22”%22)%3B%0A%0ASqlConnection%20sql%3D%20new%20SqlConnection(…)%3B%0Asql.Open()%3B%0Asqlstring%3D%40%22SELECT%20*%22%20%2B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%20FROM%20client%20WHERE%20name%3D%20’%22%20%2B%20productName%2B%20%22’%20or%20price%20%3D%22%20%2B%20price%3B%0ASqlCommand%20cmd%20%3D%20new%20SqlCommand(sqlstring%2Csql)%3B”/]
假設駭客輸入下列攻擊字串
Book’ or 1=1 —, |
由於 ‘ 會被轉換成雙引號, 造成整個 SQL 語句無效, 所以攻擊會失敗
但是這樣的防護方式如果遇到有數值得輸入時, 還是會受到 SQL Injection
因此, 駭客可以透過數值的輸入, 因為數值輸入不需要引號,
例如將價格輸入為 100; shutdown —
select * FROM client WHERE ID = 'Book'' or 1=1 -- ' or price=100; shutdown --
|
除此之外, 駭客可以使用 char(0x27)來代替單引號, 也可以避開過濾單引號的偵測防護
迷思二: 用 Stored Procedure
使用 Stored procedure 就一定安全嗎?
這個範例 Store procedure 引用一個外部參數 ProductName執行
[pastacode lang=”java” message=”” highlight=”” provider=”manual” manual=”string%20ProductName%20%3D%20…%3B%20%2F%2F%20Assume%20get%20the%20ProductName%20input%20from%20user%0A%0ASqlConnection%20sql%3D%20new%20SqlConnection(…)%3B%0Asql.Open()%3B%0A%0A%2F%2F%20Execute%20the%20Store%20procedure%20with%20the%20ProductName%20input%0Asqlstring%3D%40%22exec%20sp_GetName%20’%22%20%2B%20ProductName%20%2B%20%22’%22%3B%0ASqlCommand%20cmd%20%3D%20new%20SqlCommand(sqlstring%2Csql)%3B”/]
駭客輸入字串如下, 造成 SQL 語句無效, SQL Injection攻擊會失敗
exec sp_GetName 'Book' 1=1 -- '
|
但是駭客還是可以輸入下列 SQL 語句, 除了會造成查詢Book之外, 還會新增一筆資料
exec sp_GetName 'Book' insert into client values(1000, 'Book2') -- '
|
最危險的 Store procedure範例就是可以讓使用者自由輸入 SQL 語句, 範例如下
[pastacode lang=”java” message=”” highlight=”” provider=”manual” manual=”CREATE%20PROCEDURE%20sp_myStore%20%40input%20varchar(256)%0AAS%0A%20%20%20%20exec(%40input)”/]
迷思三: 使用 SP_executeSQL就可以自動防護 SQL injection
許多的迷思認為只要使用 SP_executeSQL 就可以避免 SQL injection,
但是如果沒有正確的定義參數
還是會受到 SQL injection:
[pastacode lang=”sql” message=”” highlight=”” provider=”manual” manual=”%20%20set%20%40cmd%20%3D%20N%E2%80%98SELECT%20*%20FROM%20sys.database_principals%20WHERE%20name%20%3D%20%E2%80%9D%E2%80%99%20%2B%20%40name%20%2B%20N%E2%80%9D%E2%80%9D%0A%0A%20%20set%20%40parameters%20%3D%20null%20–%E6%B2%92%E6%9C%89%E5%AE%9A%E7%BE%A9%E5%8F%83%E6%95%B8%20%20%E9%82%84%E6%98%AF%E6%9C%83%E5%B0%8E%E8%87%B4%20SQL%20injection%20%0A%0A%20%20EXEC%20sp_executesql%20%40cmd%2C%20%40parameters”/]
正確的使用方式如下:
[pastacode lang=”sql” message=”” highlight=”” provider=”manual” manual=”%20%20set%20%40parameters%20%3D%20%E2%80%98%40name%20sysname%E2%80%99%0A%0A%20%20EXEC%20sp_executesql%20%40cmd%2C%20%40parameters%2C%20%40name%20%3D%20%40name%0A%0A”/]
正確防護之道
SQL Injection正確的解決方式為何呢? 下列兩者缺一不可!
- 1. Parameterized Query
- 2. Prepare Statement
程式範例
[pastacode lang=”java” message=”” highlight=”” provider=”manual” manual=”%20String%20custname%20%3D%20request.getParameter(%22customerName%22)%3B%20%2F%2F%20This%20should%20REALLY%20be%20validated%20too%0A%20%2F%2F%20perform%20input%20validation%20to%20detect%20attacks%0A%20String%20query%20%3D%20%22SELECT%20account_balance%20FROM%20user_data%20WHERE%20user_name%20%3D%20%3F%20%22%3B%0A%20%0A%20PreparedStatement%20pstmt%20%3D%20connection.prepareStatement(%20query%20)%3B%0A%20pstmt.setString(%201%2C%20custname)%3B%20%0A%20ResultSet%20results%20%3D%20pstmt.executeQuery(%20)%3B”/]
後記
1. 筆者面試到目前為止還沒有人可以回答完整, 100% 有效防止 SQL injection 的防護方式為何?
2. 許多人回答, 不要使用 SQL, 用白名單輸入檢查, 編碼等方式, 避免動態組成 SQL 語句, 這些都是無法 100% 避免 SQL injection
3. 筆者也遇過使用 prepare statement 但是並沒有將輸入參數化
要正確有效的防止 SQL Injection, 就要靠:
- Parameterized Query + Prepare Statement 兩者缺一不可
- Parameterized Query + Prepare Statement 兩者缺一不可
- Parameterized Query + Prepare Statement 兩者缺一不可
重要的事情要說三次
SQLi更多線上教學參考
Here is the Link: https://www.guru99.com/learn-sql-injection-with-practical-example.html
by Alex Nordeen
參考
-
- New SQL Truncation Attacks And How To Avoid Themhttp://msdn.microsoft.com/msdnmag/issues/06/11/SQLSecurity/default.aspx
-
- Stop SQL Injection Attacks Before They Stop Youhttp://msdn.microsoft.com/msdnmag/issues/04/09/sqlinjection/default.aspx
- Second-order Code Injection Attacks (http://www.ngssoftware.com/papers/SecondOrderCodeInjection.pdf)