1. 程式人生 > >儲存過程之外:SQL注入深入防禦

儲存過程之外:SQL注入深入防禦

幾年以前,對開發者提及”SQL注入”或者要求採取一個”深入防禦”的措施,你大概會遭白眼。如今,越來越多的人聽過”SQL注入”攻擊而且開始關注這些攻擊出現帶來的潛在危險,但是大多數開發者仍然欠缺如何防止SQL注入攻擊的知識,而當問及他們的應用軟體如何防禦SQL注入時,他們通常回答:“很簡單,只要使用儲存過程”。我們可以預見的是,使用儲存過程對於你的防禦策略來說是非常好的開端,但是僅此一步卻不夠。你需要採用一個深入防禦策略。

如果你不熟悉SQL注入攻擊和它們對你的應用軟體的潛在危險,請參考MSDN的文章 “SQLInjection” (http://msdn2.microsoft.com/en-us/library/ms161953.aspx)。

僅僅依賴儲存過程而無法執行一個深入防禦的問題在於你真的只指望儲存過程開發者為你提供安全。類似於下面SQLServer程式碼用來鑑別一個使用者的儲存過程非常常見:

ALTER PROCEDURE LoginUser
(
@UserID [nvarchar](12),
@Password [nvarchar](12)
)
AS
SELECT * FROM Users WHERE UserID = @UserID AND Password = @Password
RETURN


這個儲存過程看起來非常安全,但是考慮一下這個:

ALTER PROCEDURE LoginUser
(
@UserID [nvarchar](12),
@Password [nvarchar](12)
)
AS
EXECUTE (‘SELECT * FROM Users WHERE UserID = ‘’’ + @UserID + ‘’’
AND Password = ‘’’ + @Password + ‘’’’)
RETURN

通過建立一個特別的SQL宣告,而且把它放到儲存過程程式碼的EXECUTE函式中,我們真的可以生成一個儲存過程SQL注入。當你使用控制程式碼來寫儲存過程的時候,這個更加容易,它在Microsoft SQL Server 2005中以新的方式支援:

[Microsoft.SqlServer.Server.SqlProcedure]
public static void LoginUser(SqlString userId, SqlString password)
{
using (SqlConnection conn = new SqlConnection(“context connection=true”))
{
SqlCommand selectUserCommand = new SqlCommand();
selectUserCommand.CommandText = “SELECT * FROM Users WHERE UserID = ‘”
+ userId.Value + “’ AND Password = ‘” + password.Value + “’”;
selectUserCommand.Connection = conn;

conn.Open();
SqlDataReader reader = selectUserCommand.ExecuteReader();
SqlContext.Pipe.Send(reader);
reader.Close();
conn.Close();
}
}


甚至就算你是寫儲存過程的那個人,你通常不能確定其他人會在你後面在應用軟體配置以後改變程式碼。關於Web應用這尤其可能,而這也是為什麼一個需要一個深入防禦策略。

明顯地,這個問題的解決是採用一個深入防禦策略。你應該繼續使用儲存過程和引數化任何有必要的查詢,但是你也應該設法建立你的深入防禦策略來保證傳給這些儲存過程的的引數和查詢的驗證。在我們上面的使用者鑑定例子中,“bobsmith”可能是一個有效的使用者ID,但是“SELECT * FROM tblCreditCards”或許不是。對於驗證使用者輸入使用你的深入防禦策略的一個好的方式是對它採用規範化的表達規則。你能使用在System.Web.UI.WebControls名字空間中的RegularExpressionValidator控制尋找來驗證Web表格資料,而且你可以使用在theSystem.Text.RegularExpressions 名字空間中Regex類尋找來驗證任何類別的文字資料。這裡有一個Web表格的例子,在把使用者輸入傳遞給資料庫前對它進行驗證。

protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
// We allow only alphanumeric input
Regex allowRegex = new Regex(“^[a-zA-Z0-9]*$”);
if ((!allowRegex.IsMatch(textBoxUserId.Text))
|| (!allowRegex.IsMatch(textBoxPassword.Text)))
{
labelErrorMessage.Text = “Invalid user ID or password.”;
return;
}
else
{
// Call the login stored procedure

}
}
}

一個更加徹底的深入防禦策略是使用一個允許輸入聯合模式(也被認為是“優選名單”)和拒絕輸入模式(或者稱為”黑名單”)。使用者的輸入必須匹配優選名單模式(或者說至少一個優選名單模式,如果不多於一個的話)而且不和黑名單模式匹配(或者說任何黑名單模式)。如果在你的允許輸入表中允許類似省略號這樣的非字元輸入,在深度防禦策略中,你應該明確的使用黑名單模式。

// We allow alpha characters, spaces, and apostrophes as input
Regex allowRegex = new Regex(@“^[a-zA-Z\s\’]*$”);
// But we disallow common SQL functions
Regex disallowRegex = new Regex(“(union|select|drop|delete)”);
if ((!allowRegex.IsMatch(textBoxLastName.Text)) || (disallowRegex.IsMatch(textBoxLastName.Text)))
{
labelErrorMessage.Text = “Invalid name.”;
return;
}


最後,我們必須論及加入損害控制到你的深入防禦策略。如果一個黑客真的找到了一個對你的資料庫執行SQL命令的途徑,他可能會造成什麼樣的損害呢?如果你的應用程式作為一個管理員使用者連線到資料庫,象Microsoft SQL Server的”sa”使用者,損害甚至會很嚴重。他不僅僅能看錶中的資料,他也能增加他自己的新資料或者改變已經存在資料的值。設想一個線上購物站點,所有的商品專案價格標成低於一個美分。他能夠增加新的使用者或者刪除已經存在使用者。他能刪除行,表或者甚至整個資料庫。你能通過應用最少許可權原則到你的深入防禦策略減輕這個風險:使你的應用軟體作為一個只有足夠執行必需動作的許可,而沒有其它更多的許可。如果你的應用程式只是從一個數據庫中讀資料,去掉資料庫使用者插入,更新和刪除的許可。如果應用程式只需要對一個產品目錄資料庫進行存取(舉例來說),確保使用者不能存取定購歷史資料庫。永遠不要指定”sa”或者任何管理員使用者作為資料庫使用者。

通過採用一個深入防禦策略,你可以避免大一個SQL注入攻擊導致你應用程式的多數或者所有的損害。就很多原因包括提高安全來說,使用儲存過程是一個很好的主意,但是一定不要依賴它們提供你所有的安全。總是驗證使用者輸入,而且採用最少許可權原則來減小一個成功的攻擊能引起的損害。

關於作者

Bryan Sullivan是SPI Dynamics 一個Web應用軟體安全產品公司的開發經理。Bryan管理DevInspect 和 QAInspect Web 安全產品,這些產品幫助程式設計師在整個開發和測試過程中維護應用程式的安全。他在Georgia Tech獲得本科學位,而且有11年資訊科技產業工作經驗。他也對AVDL有所貢獻,這已經成為應用軟體安全行業的一個標誌。

相關推薦

儲存過程之外SQL注入深入防禦

幾年以前,對開發者提及”SQL注入”或者要求採取一個”深入防禦”的措施,你大概會遭白眼。如今,越來越多的人聽過”SQL注入”攻擊而且開始關注這些攻擊出現帶來的潛在危險,但是大多數開發者仍然欠缺如何防止SQL注入攻擊的知識,而當問及他們的應用軟體如何防禦SQL注入時,他們通常

滲透測試SQL注入攻擊(ASP)

分類: 滲透測試 SQL注入攻擊是黑客對資料庫進行攻擊的常用手段之一。隨著B/S模式應用開發的發展,使用這種模式編寫應用程式的程式設計師也越來越多。但是由於程式設計師的水平及經驗也參差不齊,相當大一部分程式設計師在編寫程式碼的時候,沒有對使用者輸入資料的合法性進行判斷,使應用程式存在安全隱患。

mysql儲存過程舉例100以內的整數除以2、4、6、8的結果,相加等於多少

學習儲存過程:首先知道它是幹嘛的,  概念:將一組sql語句,完成一個特定的功能,稱之為儲存過程, 寫儲存過程:只能建立、替換、刪除 DROP PROCEDURE IF EXISTS sum; -- procedure 存在則先刪除 create procedure `su

Web安全之SQL注入

條件 使用者可以接觸並修改傳送到伺服器的內容 URL判斷 and 1=1 and 1=2 依據返回資訊判斷 整形 ’ 同上 字元型判斷 -1 / +1 回顯上個頁面 整形 and sleep(12)

mybaits(查詢與別名、日誌框架顯示sql語句、物件屬性和資料庫表字段不匹配resultMap使用、mysql資料查詢分頁、執行sql儲存過程、動態SQL語句)

主要是各種配置檔案,建議把整個專案搬到自己電腦上慢慢看。 建立maven專案 首先是各種配置檔案: pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://m

db2怎樣將儲存過程當中的SQL語句打印出來?

 1)首先需要建立一個OUT 引數 例如:OUT T VARCHAR(10000)       2)其次需要在prepare s1 from v_sql1;之前設定set t = v_sql1;(首次,以後set t = t||v_sql1;)       3)而後執行cal

sql server 查看錶、檢視、觸發器、儲存過程等組成sql查詢語句

1. 檢視使用者表 select name from sys.tables select name from sys.objects where type='U' select name from sysobjects where xtype='U'   其中type

【Web安全與防禦】簡析Sql注入防禦措施

個人資訊 就職: 聚項資訊科技有限公司 職位:中級Java開發工程師 負責:上汽系統開發與維護 院校:河南理工大學 專業:軟體工程12級 郵箱:[email protected] Q Q :10101000101001010111 1101111010

SQL增刪改查,迴圈,觸發器,儲存過程,以及sql語法

                                      可以直接貼上程式碼使用 --建立資料庫命令 create database j1216 on ( name=j1216, filename='E:\shuju\j1216\j1216.mdf', s

mysql 儲存過程動態拼接sql並執行賦值

CREATE DEFINER = CURRENT_USER PROCEDURE `NewProc`(in _xnb varchar(50)) BEGIN ## 定義變數 DECLARE _num FLOAT(14,6) DEFAULT 0; ## @表示全域性變數 相當於php

mysql儲存過程執行動態sql語句並返回值

Java程式碼 set @sql=’xxx’; prepare stmt from @sql; execute stmt; deallocate prepare stmt; select @curd1; set @sql=’xxx’; prepare stmt f

白話SQL注入

SQL注入 最近在整理web安全方面的知識,發現以前寫的這一篇有bug,於是重新編輯發表了一下,下面是分享內容。 SQL注入原理解釋 網上和書上對SQL注入講的感覺挺複雜的,但是就我理解來看,SQL注入就是利用資料庫查詢語句的漏洞,使用者通過特殊的輸入,構

儲存過程、動態sql、for、if

create or replace procedure ---- is COLLECTDATE varchar2(8) := to_char(sysdate-1,'yyyymmdd'); -- 統計日期 yyyymmdd INIT_STAT

SQL2005在新建複製 找不到儲存過程 錯誤2812 的解決方法

標題: 新建釋出嚮導 ------------------------------ SQL Server 無法建立釋出“XXXXX釋出”。 ------------------------------ 其他資訊: 執行 Transact-SQL 語句或批處理時發生了異常。

linux之mysql資料庫搭建及sql注入防禦

mysql中文手冊下載地址:/data/2244392 sql注入各種姿勢:/10319657/1828167 sqlmap注入神器詳解:/10319657/1841241 資料庫分為三種基本形式 : (其實這些都是眾所周知的,只是為了知識的完整性,簡單的帶過

通過系統儲存過程手動執行SQL Server中的Job

目錄 系統儲存過程sp_start_job 在SQL Server中,若想通過T-SQL指令碼手動執行SQL Server Agent中的Job(作業任務),則可使用系統儲存過程sp_star

mysql儲存過程 在動態SQL內獲取返回值

MySql通用分頁儲存過程 過程引數 p_cloumns varchar(500),p_tables varchar(100),p_where varchar(4000),p_order varchar(100),p_pageindex int,p_pagesize int

mysql儲存過程接收動態sql返回值

一、今天需要用到mysql儲存過程接受動態sql的返回值,特此做以下記錄 二、具體如下 -- BS追加公能欄位 獲取型別和公能分組ID declare vPartName,vType,vSql,vId varchar(100); declare vPartGroupId i

mysql 儲存過程 執行動態sql

使用mysql的儲存過程執行動態sql語句 delimiter // create procedure proce2(in old varchar(100), in newT varchar(1

mysql儲存過程在動態SQL內獲取返回值

DROPPROCEDUREIFEXISTS stat_cube.sp_get_end_date;CREATEPROCEDURE stat_cube.`sp_get_end_date`( p_sp_name varchar(50), out p_ret_date date )BEGINdeclare src_1