以前一直以為asp.net調用mssql資料庫,只要是調用時用預存程序來操作資料庫,是安全的。原來是錯誤的,asp.net裡的SqlDataAdapter裡存在sql注入的漏洞。對於asp.net開發人員來說在使用SqlDataAdapter的時候要注意了。下面先介紹下.net操作資料庫的這個SqlDataAdapter。
SqlDataAdapter:
用於填充 DataSet 和更新 SQL 資料庫的“一組”資料命令和“一個”資料庫連接。
SqlDataAdapter不但可以操作多個SQL命令,而且還可以操作一個SQL命令
SqlCommand:
對 SQL 資料庫執行的“一個”SQL 陳述式或預存程序。
SqlCommand只能操作一個SQL命令
問題就出來在SqlDataAdapter可以調用多個SQL命令裡。這樣如果你給SqlDataAdapter參數的sql語句不做處理的話。別人就可以很方便的使用Sql來注入。
下面看下具體的執行個體:
asp.net 裡test.cs檔案的程式:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString.Count == 1)
{
DbServer dbserver = new DbServer();
System.Data.DataSet ds = new DataSet();
string tablename = "table1";
string strsql = string.Empty;
strsql = " exec dtc_CompeteInfo " + Request.QueryString.Get(0);
dbserver.FillDataset(strsql, ds, tablename);
//下面省略處理
----
----
}
}
DbServer 類裡的FillDataset函數為:
// 根據SQL查詢並用記錄集填充DataSet
public void FillDataset(string sql, DataSet ds, string tablename)
{
SqlConnection conn = new SqlConnection(CONNECTIONSTR);
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
da.Fill(ds, tablename);
da.Dispose();
conn.Close();
conn.Dispose();
da = null;
conn = null;
}
上面的程式,如果正常的執行http://www.xxx.com/test.aspx?id=100 。
程式最後執行:SqlDataAdapter da = new SqlDataAdapter('exec dtc_CompeteInfo 100', conn);
dtc_CompeteInfo為一個預存程序,100為給這個預存程序的傳遞的參數值。程式正常執行。
但是當你構造這樣一個地址http://www.xxx.com/test.aspx?id=100;update t_table set t_a='admin' 傳遞的時候。我們分析下會出現怎麼樣的情況呢?由於SqlDataAdapter能執行一組SQL命令。這樣程式實際上變成strsql=" exec dtc_CompeteInfo 100;update t_table set t_a='admin'。然後在SqlDataAdapter執行exec dtc_CompeteInfo 100和update t_table set t_a='admin'二個sql語句了。從而到達了注入的目的。想想如果網站串連資料庫的帳號是sa的話。可以做什麼呢?什麼都可以做。增加新使用者,取得最高許可權。這台電腦就完全控制了。