星期二, 7月 06, 2010

我的 SQL injection 講稿

SQL injection,Injection 即為 "注入" 的意思SQL 指令被注入功擊Code會如何?
SQL injection 常常發生於類似的代碼 String statement = "SELECT * FROM userinfo WHERE id = " + a_variable + ";"此例,a_variable 是一個 string,當 a_variable = “;DROP” 時組 合起變 statement 即變成SELECT * FROM userinfo WHERE id=1;DROP sss -- TABLE users

注意 ;DROP 的位置
一個指令被切成左右兩個指令,每個指令有正確的結尾符號 ( ; ) 因此是正確的 SQL 指令。一個指令分成兩個卻在同一個命令列中即稱為 "綜合指令" (Batch SQL Statement)

那麼要如何防止 Batch SQL Statement 的產生?

Answer:
我們可以利用 SQL Server 本身的除錯功能
如 果框起來如何? 如
SELECT * FROM userinfo WHERE id='1;DROP' TABLE users;
還有沒有其它的方法?

我們來 Youtube 看一個實際的 Hacking 體驗
http://www.youtube.com/watch?v=jMQ2wdOmMIA&playnext_from=TL&videos=709J1SkZFj0

實際案例:
Data Access Layer 安全漏洞

假如有一個函數 CommentsTop()
他有兩個參數
OrderID - int
Id - string
在此例 Id 是數字,很明顯地,Id 用 String,後面的碼沒寫好的話,就可能發生 SQL Injection


如何寫出沒有 SQL Injection 問題的 Code:
http://msdn.microsoft.com/en-us/library/ff648339.aspx


進階

交易 Transaction
模組化 ADO.NET Wrapper Library
元件設計 - ViewState, PostData, Session

恩考方向
ASP.NET 最常見的 SQL 使用方式為 ADO.NET
為 什麼會有 ADO.NET? (關於 SQL Statement)
提示:ADO.NET 前身,ODBC
ADO.NET 能做什麼,不能做什麼? (效能,安全,可利用性如何平衡)


.NET 3.5 LINQ 如何利用 Strong-Typing 又能取出資料,並 Join 兩個 Table

public static FuncIQueryable> RecentPostTopicList_query = System.Data.Linq.CompiledQuery.Compile(
(EruruDataContext context, Eruru.Data.DAL.AspnetUsers user, int maxResult) =>
context.EruruPost.Where(x => x.UserId == user.UserId && x.PostTypeId == PostLogic.BLOG_POST_TYPE_ID)
.OrderByDescending(x => x.PublishedDate)
.Take(maxResult)
.Select(x => new { PostId = x.PostId, UserName = user.UserName, Title = x.Title, PublishedDate = x.PublishedDate })
.Cast()
);


public static FuncIQueryable> RandomPostTopicList_query = System.Data.Linq.CompiledQuery.Compile(
(EruruDataContext context, Eruru.Data.DAL.EruruArea area, int maxResult) =>
from posts in
(from r in context.EruruPost
where r.AreaId == area.AreaId && r.PostTypeId == PostLogic.BLOG_POST_TYPE_ID
orderby EruruDataContext.Default.Random()
select r).Take(maxResult)
join user in context.AspnetUsers on posts.UserId equals user.UserId into temppostuser
from postuser in temppostuser.DefaultIfEmpty()
select (object)new { PostId = posts.PostId, UserName = postuser.UserName, Title = posts.Title }
);

沒有留言: