###### tags: `2020 Kali讀書會-資安小聚` ## 你知道後端仔是如何阻礙你的 SQL injection 的嗎? ### Sponge --- ## 講者介紹 * 現任 後端工程師 (BackEnd) * 曾任 資料庫設計師 (DataBaseDesigner) * 曾任 資料庫管理師 (DataBaseAdministrator) --- ## 分享流程 * 資料庫介紹 * 防禦手段介紹 * 實際演練 --- ## HackMD 共用筆記 ![](https://i.imgur.com/rpYbTnB.png) [2020 Kali讀書會-資安小聚](https://hackmd.io/RhHpk1rTQEC5gPUUOfrfug) --- ## 網站的構成 ![](https://i.imgur.com/T8Ke7g9.png) --- ## 資料庫的種類 ![](https://i.imgur.com/aLijANb.png) --- ## 那個資料庫最熱門呢? https://db-engines.com/en/ranking ![](https://i.imgur.com/yh592wF.png) --- ## 讓我們來針對 MS-SQL 來介紹 - 原因 : * 其 SQL 方言多,獨立命名為 Transact-SQL * 討論度排名為第三,市佔率也並不低 * 我比較熟悉 MS-SQL 的開發模式 --- ## MS-SQL 的資料庫階層 資料庫是有階層的,而且 MS-SQL 比別人多一層 ```SQL --MySQL : database => table => column SELECT * FROM `Test`.`Sanple`.`id` ``` ```SQL --MS-SQL : database => table => schema => column SELECT * FROM [Test].[dbo].[Sanple].[id] ``` schema 是可以自訂的,預設皆為 dbo --- ## SQL - SQL (Structured Query Language) - 結構化查詢語言 - 對資料庫進行操作(插入 刪除 查詢) - 在不同的資料庫上會有些微的不同 - Oracle MySQL MSSQL Postgresql --- ## T-SQL 與 MySQL 語法異同 欄位標示與限定筆數的不同 ```sql --MySQL : SELECT * FROM `Test`.`Sanple`.`id` LIMIT 10 ``` ```sql --MS-SQL : SELECT TOP 10 * FROM [Test].[dbo].[Sanple].[id] ``` 取得版本號的語法相同 ```sql --MySQL&MS-SQL : SELECT @@VERSION ``` --- ## 登入功能的 SQL 實現 ```sql SELECT COUNT(*) FROM [dbo].[user] WHERE uid='guest' AND passward = 'xxxxxxx' ``` ```sql SELECT COUNT(*) FROM user WHERE Uid='INPUT' AND passward = 'INPUT' ``` --- ![](https://i.imgur.com/MSm82hK.jpg) --- ## 開發人員的防禦方法 1. 不顯示詳細錯誤訊息給使用者,避免透過 SQL Error Message 猜測資料表、查詢語法的的結構 2. 過濾使用者傳入的參數(-- 、//、/**/….) 3. 使用參數化的查詢方法,不使用 SQL 拼接 4. 透過 ORM 工具撰寫 LINQ 語法與資料庫溝通 --- ## 甚麼是參數化的查詢? ```sql DECLARE @USER nvarchar(20) = 'guest',@PWD nvarchar(30) = 'xxxxxxx' SELECT COUNT(*) FROM [dbo].[user] WHERE [uid] = @USER AND [passward] = @PWD ``` --- ## 程式要如何實作參數化查詢 ```csharp= SqlCommand cmd = new SqlCommand( "SELECT COUNT(*) FROM user WHERE uid = @uid AND passward = @passward", conn); cmd.Parameters.AddWithValue("@uid", userName); cmd.Parameters.AddWithValue("@passward", password); conn.Open(); return ((int)cmd.ExecuteScalar() > 0); ``` --- ## 參數化的查詢可以阻止攻擊? 在使用參數化查詢的情況下,資料庫伺服器不會將參數的內容視為SQL指令的一部份來處理,而是在資料庫完成SQL指令的編譯後,才套用參數執行,因此就算參數中含有具破壞性的指令,也不會被資料庫所執行。 --- ## 那麼甚麼是 ORM? - Object-Relation Mapping - ORM - 對象關係映射 - 用程式語言而非 SQL 來操作資料庫 - 可透過同一套語法操作不同資料庫,降低耦合 - 最終轉譯成 SQL - 由於經由中間層轉譯,效能會降低 - 還是有風險,ORM Injection --- ## ORM 如何實作 ```csharp= protected void Login(object sender, EventArgs e) { NorthwindDataContext context = new NorthwindDataContext(); if( ( from s1 in context.user where s1.uid == TextBox1.Text && s1.passward == TextBox2.Text select s1).Count() = 1 ) Label1.Text = "success"; else Label1.Text = "error"; } ``` --- ## 還是有網站可以攻擊? - 系統老舊沒有維護 - 效能考量 - 有進行防護但仍有漏洞 --- ## 那該如何防禦SQLInjection 目前最佳解為參數化查詢,但由於會影響效能與降低開發速度,因此多採用 ORM 框架來防禦, 現今主流的 ORM 框架如 .NET 系列的 Dapper、Entity framework --- ## 那麼,來試試看吧 ### 我準備了一個 blazor 專案供大家遊玩 ![](https://i.imgur.com/d6IbSqN.png) --- ## 成功進來會顯示恭喜喔 ![](https://i.imgur.com/YoxC26h.png) --- ## 會記錄登入的名稱與 ip ![](https://i.imgur.com/YL0FeNc.png) --- ## 參考資料 - [stackoverflow_parameterized-query](https://stackoverflow.com/questions/4712037/what-is-parameterized-query) - [stackoverflow_orm](https://stackoverflow.com/questions/37189863/which-orm-should-i-be-using-for-net-in-2016-to-talk-to-sql-server) - [db-engines](https://db-engines.com/en/ranking) - [ORM_Injection](https://www.owasp.org/index.php/Testing_for_ORM_Injection_(OTG-INPVAL-007)) --- ## 希望大家能有所收穫 ### 如有錯誤請不吝告知,十分感謝 --- ```
{"metaMigratedAt":"2023-06-15T02:57:43.170Z","metaMigratedFrom":"Content","title":"Untitled","breaks":true,"description":"現任 後端工程師 (BackEnd)","contributors":"[{\"id\":\"3a9f7467-86ee-4e65-969a-d2212f5ccee7\",\"add\":4449,\"del\":632}]"}
    593 views
   Owned this note