界: Input Validation and Representation

輸入驗證和表示法問題是由中繼字元、替代編碼和數值表示法引起的。信任輸入會導致安全問題。問題包括:「Buffer Overflows」、「Cross-Site Scripting」攻擊、「SQL Injection」及其他許多問題。

12 找到的項目
弱點
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。

2. 資料用於動態地建立 SQL 查詢。
範例 1:以下程式碼動態建構並執行 SQL 查詢,該查詢是用來搜尋屬於使用者的發票。此查詢會將顯示的項目限制為與目前已驗證之使用者的名稱相同的使用者。


...
v_account = request->get_form_field( 'account' ).
v_reference = request->get_form_field( 'ref_key' ).

CONCATENATE `user = '` sy-uname `'` INTO cl_where.
IF v_account IS NOT INITIAL.
CONCATENATE cl_where ` AND account = ` v_account INTO cl_where SEPARATED BY SPACE.
ENDIF.
IF v_reference IS NOT INITIAL.
CONCATENATE cl_where "AND ref_key = `" v_reference "`" INTO cl_where.
ENDIF.

SELECT *
FROM invoice_items
INTO CORRESPONDING FIELDS OF TABLE itab_items
WHERE (cl_where).
...


此程式碼要執行的查詢如下 (假設 v_account 和 v_reference 不是空白):


SELECT *
FROM invoice_items
INTO CORRESPONDING FIELDS OF TABLE itab_items
WHERE user = sy-uname
AND account = <account>
AND ref_key = <reference>.


但是,由於該查詢是由串聯固定基礎查詢字串和使用者輸入字串所動態建構而成,因此會成為 SQL injection 攻擊的目標。如果攻擊者為 v_reference 輸入字串 "abc` OR MANDT NE `+",為 v_account 輸入字串「1000」,那麼查詢將會變更為:


SELECT *
FROM invoice_items
INTO CORRESPONDING FIELDS OF TABLE itab_items
WHERE user = sy-uname
AND account = 1000
AND ref_key = `abc` OR MANDT NE `+`.


新增 OR MANDT NE `+` 條件會導致 WHERE 子句永遠評估為 true,因為用戶端欄位永遠不可能等於文字 +,所以此查詢邏輯上可等同於以下較簡化的查詢:


SELECT * FROM invoice_items
INTO CORRESPONDING FIELDS OF TABLE itab_items.


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將傳回所有儲存在 invoice_items 表中的項目,而不考慮指定的使用者為何。

範例 2:在此範例中,我們將考慮在程式中使用 ADBC API,以允許員工更新其地址。


PARAMETERS: p_street TYPE string,
p_city TYPE string.

Data: v_sql TYPE string,
stmt TYPE REF TO CL_SQL_STATEMENT.

v_sql = "UPDATE EMP_TABLE SET ".

"Update employee address. Build the update statement with changed details
IF street NE p_street.
CONCATENATE v_sql "STREET = `" p_street "`".
ENDIF.
IF city NE p_city.
CONCATENATE v_sql "CITY = `" p_city "`".
ENDIF.

l_upd = stmt->execute_update( v_sql ).



如果感到不滿的員工輸入字串,例如為參數 p_street 輸入 "ABC` SALARY = `1000000",則應用程式允許使用修訂的薪資更新資料庫!

避免 SQL injection 攻擊的一個傳統方法是將其視為輸入驗證問題,只接受安全值的允許清單,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

References
[1] SAP OSS notes 1520356, 1487337, 1502272 and related notes.
[2] S. J. Friedl SQL Injection Attacks by Example
[3] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[4] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[5] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.abap.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可能會讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。



2. 資料用來動態建構 SQL 查詢。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var username:String = String(params["username"]);
var itemName:String = String(params["itemName"]);
var query:String = "SELECT * FROM items WHERE owner = " + username + " AND itemname = " + itemName;

stmt.sqlConnection = conn;
stmt.text = query;
stmt.execute();
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.actionscript.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。

2. 資料用來動態建構 SQL 查詢。
範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示 owner 與目前已驗證使用者名稱相符的項目。


...
string userName = ctx.getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";
sda = new SqlDataAdapter(query, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'); DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.dotnet.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。

2. 資料用來動態建構 SQL 查詢。
範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
ctx.getAuthUserName(&userName); {
CString query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ request.Lookup("item") + "'";
dbms.ExecuteSQL(query);
...
範例 2:或者,也可以使用下列程式碼利用 SQLite 取得相似的結果:


...
sprintf (sql, "SELECT * FROM items WHERE owner='%s' AND itemname='%s'", username, request.Lookup("item"));
printf("SQL to execute is: \n\t\t %s\n", sql);
rc = sqlite3_exec(db,sql, NULL,0, &err);
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 3:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'); DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。所以,在此案例中,SQL 查詢中最後的一個單引號將會被作為註釋處理。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[5] Parameterized CRecordset and CDatabase for SQL Server
[6] Parameterizing a Recordset Microsoft
[7] ODBC API Reference: SQLNumParams() Microsoft
[8] ODBC API Reference: SQLBindParameter() Microsoft
[9] OLE DB Reference: ICommandWithParameters Microsoft
desc.dataflow.cpp.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。

2. 資料用於動態地建立 SQL 查詢。
範例 1:以下程式碼動態地建構並執行一個 SQL 查詢,該查詢是用來搜尋與所指定的名字相符的項目。此查詢將顯示的項目限制在,與目前被驗證的使用者的名稱相同的所有者。


...
ACCEPT USER.
ACCEPT ITM.
MOVE "SELECT * FROM items WHERE owner = '" TO QUERY1.
MOVE "' AND itemname = '" TO QUERY2.
MOVE "'" TO QUERY3.

STRING
QUERY1, USER, QUERY2, ITM, QUERY3 DELIMITED BY SIZE
INTO QUERY
END-STRING.

EXEC SQL
EXECUTE IMMEDIATE :QUERY
END-EXEC.
...


以下為此程式碼將執行的查詢:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itm 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:在此範例中,我們會考慮將不同的惡意值傳送到 Example 1 中建構和執行之查詢所帶來的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在支援的資料庫上,此類攻擊會允許攻擊者針對資料庫執行任意的指令。

請注意這對連字符號 (--),其在大部分的資料庫伺服器上指出剩餘的陳述式都將視為註釋且不執行 [4]。在此案例中,註釋的作用是從修改的查詢中移除剩餘的單引號。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法是將其視為輸入驗證問題,只接受安全值的允許清單,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.cobol.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。

2. 資料用於動態地建立 SQL 查詢。
範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
<cfquery name="matchingItems" datasource="cfsnippets">
SELECT * FROM items
WHERE owner='#Form.userName#'
AND itemId=#Form.ID#
</cfquery>
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemId = <ID>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 Form.ID 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 Form.ID 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemId = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 hacker 的攻擊者在 Form.ID 中輸入字串「hacker'); DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'hacker'
AND itemId = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'hacker'
AND itemId = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.cfml.sql_injection
Abstract
使用 Java J2EE PersistenceAPI 執行透過不可信賴來源的輸入來建立的動態 SQL 陳述式,可能會讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1.資料從一個不可信賴的來源進入程式。



2.資料用來動態建構 SQL 查詢。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名字的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
final server = await HttpServer.bind('localhost', 18081);
server.listen((request) async {
final headers = request.headers;
final userName = headers.value('userName');
final itemName = headers.value('itemName');
final query = "SELECT * FROM items WHERE owner = '"
+ userName! + "' AND itemname = '"
+ itemName! + "'";
db.query(query);
}
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串 name' OR 'a'='a,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


查詢必須只傳回經驗證使用者所擁有的項目,但簡化查詢可讓攻擊者不再受到此要求所限制。因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開陳述式的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類攻擊可讓攻擊者對資料庫執行任意指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的結尾單引號移除。在不允許以此方式使用註釋的資料庫中,一般攻擊者仍然可以使用類似 Example 1 中所示的訣竅進行攻擊。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,對於實作拒絕清單方法,總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的欄位當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動在 SQL 查詢中避開特殊字元的輸入有一定作用,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL Injection 攻擊的普遍建議方法為使用預存程序。雖然預存程序可防止某些類型的 SQL Injection 攻擊,但是對於大多數的攻擊還是無能為力。預存程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳遞到參數的陳述式類型。但是,雖然有許多的限制方法,仍有許多危險的陳述式可以傳入儲存的程序中。所以再次強調,儲存的程序可以避免部分盜取情況,但無法保護您的應用程式免於 SQL Injection 攻擊。
desc.dataflow.dart.sql_injection
Abstract
透過來自不可信賴來源的輸入建構動態 SQL 陳述式可讓攻擊者修改陳述式的意義,或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1.資料從一個不可信賴的來源進入程式。

2.資料用來動態建構 SQL 查詢。
範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名字的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
rawQuery := request.URL.Query()
username := rawQuery.Get("userName")
itemName := rawQuery.Get("itemName")
query := "SELECT * FROM items WHERE owner = " + username + " AND itemname = " + itemName + ";"

db.Exec(query)
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是透過串聯固定基礎查詢字串和使用者輸入字串,由程式碼以動態方式建構而成,所以只有在 itemName 不包含單引號字元時,查詢才會正確運作。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串 name' OR 'a'='a,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


查詢必須只傳回經驗證使用者所擁有的項目,但簡化查詢可讓攻擊者不再受到此要求所限制。因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許同時執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開陳述式的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類攻擊可讓攻擊者對資料庫執行任意指令。

請注意結尾的這對連字符號 (--),這在大部分資料庫伺服器上都會將剩餘的陳述式視為註釋而不予執行。[4].在此案例中,註釋字元會從修改的查詢中將剩餘的結尾單引號移除。在不允許以此方式使用註釋的資料庫中,一般攻擊者仍然可以使用類似 Example 1 中所示的訣竅進行攻擊。如果攻擊者輸入 "name'; DELETE FROM items; SELECT * FROM items WHERE 'a'='a" 字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,對於實作拒絕清單方法,總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可以:

- 將未列入黑名單的欄位當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動在 SQL 查詢中避開特殊字元的輸入有一定作用,但無法完全保護您的應用程式免於 SQL Injection 攻擊。

另外一個處理 SQL Injection 攻擊的普遍建議方法為使用預存程序。雖然預存程序可防止某些類型的 SQL Injection 攻擊,但是對於大多數的攻擊還是無能為力。預存程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳遞到參數的陳述式類型。但是,雖然有許多的限制方法,仍有許多危險的陳述式可以傳入儲存的程序中。所以再次強調,預存程序可以防止某些攻擊,但是並不能完全保護您的應用系統免於 SQL Injection 攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.golang.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1.資料從一個不可信賴的來源進入程式。



2.資料用來動態建構 SQL 查詢。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
String userName = ctx.getAuthenticatedUserName();
String itemName = request.getParameter("itemName");
String query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ itemName + "'";
ResultSet rs = stmt.execute(query);
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


有人認為在行動環境中,典型的 Web 應用程式弱點 (例如 SQL Injection) 不會產生影響,因為使用者為何會攻擊自己呢?但是請謹記,行動平台的本質是從多種來源下載,並在相同裝置上一起執行的應用程式。在金融應用程式旁執行惡意程式碼的可能性很高,這必然會擴大行動應用程式的受攻擊面,將程序之間的通訊包括在內。

範例 3:以下程式碼改寫 Example 1 以適用於 Android 平台。


...
PasswordAuthentication pa = authenticator.getPasswordAuthentication();
String userName = pa.getUserName();
String itemName = this.getIntent().getExtras().getString("itemName");
String query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ itemName + "'";
SQLiteDatabase db = this.openOrCreateDatabase("DB", MODE_PRIVATE, null);
Cursor c = db.rawQuery(query, null);
...


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[5] IDS00-J. Prevent SQL Injection CERT
[6] INJECT-2: Avoid dynamic SQL Oracle
desc.dataflow.java.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可能會讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。



2. 資料用來動態建構 SQL 查詢。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
var username = document.form.username.value;
var itemName = document.form.itemName.value;
var query = "SELECT * FROM items WHERE owner = " + username + " AND itemname = " + itemName + ";";
db.transaction(function (tx) {
tx.executeSql(query);
}
)
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.javascript.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可能會讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1.資料從一個不可信賴的來源進入程式。



2.資料用來動態建構 SQL 查詢。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
$userName = $_SESSION['userName'];
$itemName = $_POST['itemName'];
$query = "SELECT * FROM items WHERE owner = '$userName' AND itemname = '$itemName';";
$result = mysql_query($query);
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.php.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。

2. 資料用於動態地建立 SQL 查詢。
範例 1:以下程式碼動態建立並執行了 SQL 查詢,該查詢是用來搜尋與所指定的名字相符的項目。此查詢將顯示的項目限制在,與目前被驗證的使用者的名稱相同的所有者。


procedure get_item (
itm_cv IN OUT ItmCurTyp,
usr in varchar2,
itm in varchar2)
is
open itm_cv for ' SELECT * FROM items WHERE ' ||
'owner = '''|| usr || '''' ||
' AND itemname = ''' || itm || '''';
end get_item;


以下為此程式碼將執行的查詢:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果一個使用者名稱為 wiley 的攻擊者為 itm 輸入字串「name' OR 'a'='a」,那麼查詢將變成:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:在此範例中,我們會考慮將不同的惡意值傳送到 Example 1 中建構和執行之查詢所帶來的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在支援的資料庫上,此類攻擊會允許攻擊者針對資料庫執行任意的指令。

請注意這對連字符號 (--),其在大部分的資料庫伺服器上指出剩餘的陳述式都將視為註釋且不執行 [4]。在此案例中,註釋的作用是從修改的查詢中移除剩餘的單引號。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法是將其視為輸入驗證問題,只接受安全值的允許清單,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。如同上述所顯示的一系列範例,儲存的程序也像其他程式碼類型一樣有弱點。儲存的程序可避免某些類型的盜取,但無法保護您的應用程式安全的免於 SQL injection 攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[5] David Litchfield Lateral SQL Injection: A New Class of Vulnerability in Oracle
desc.dataflow.sql.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可能會讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1.資料從一個不可信賴的來源進入程式。



2.資料用來動態建構 SQL 查詢。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
userName = req.field('userName')
itemName = req.field('itemName')
query = "SELECT * FROM items WHERE owner = ' " + userName +" ' AND itemname = ' " + itemName +"';"
cursor.execute(query)
result = cursor.fetchall()
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.python.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。

在此案例中,Fortify Static Code Analyzer 無法判斷資料來源是否可信賴。

2. 資料用來動態建構 SQL 查詢。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
userName = getAuthenticatedUserName()
itemName = params[:itemName]
sqlQuery = "SELECT * FROM items WHERE owner = '#{userName}' AND itemname = '#{itemName}'"
rs = conn.query(sqlQuery)
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

由於 Ruby 不是靜態輸入,因此也支援在靜態輸入的語言中可能無法使用的插入 SQL 查詢的其他點。
範例 2:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
id = params[:id]
itemName = Mysql.escape_string(params[:itemName])
sqlQuery = "SELECT * FROM items WHERE id = #{userName} AND itemname = '#{itemName}'"
rs = conn.query(sqlQuery)
...


在此案例中,要執行的預期 SQL 查詢為:


SELECT * FROM items WHERE id=<id> AND itemname = <itemName>;

您可以看到這次我們防止了在 itemName 內指定單引號的攻擊者,並且似乎遏止了 SQL injection 弱點。不過,由於 Ruby 不是靜態輸入的語言,因此,雖然 id 預期為某些變數的整數,但由於其是從使用者輸入指定的,因此也未必是數字。如果攻擊者可將 id 的值變更為 1 OR id!=1--,則由於沒有檢查 id 實際上是否為數字,SQL 查詢現在變為:


SELECT * FROM items WHERE id=1 OR id!=1-- AND itemname = 'anyValue';


請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的指令,並視為註釋不予執行 [4]。鑒於此,現在只要執行包含下列內容的 SQL 查詢:


SELECT * FROM items WHERE id=1 OR id!=1;


我們現在只要選取表格中的全部內容,無論 id 的值是否等於 1,顯然該值等於表格內的全部內容。

許多資料庫伺服器允許立即執行由分號隔開的多個 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.ruby.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。



2. 資料用來動態建構 SQL 查詢。

範例 1: 以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可搜尋符合指定名稱的使用者。 查詢僅會顯示項目所有者與提供作為路徑參數之使用者名稱相符的項目。


def doSQLQuery(value:String) = Action.async { implicit request =>
val result: Future[Seq[User]] = db.run {
sql"select * from users where name = '#$value'".as[User]
}
...
}


此查詢欲執行以下程式碼:


SELECT * FROM users
WHERE name = <userName>


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 userName 沒有包含單引號字元的時候,查詢才會正確執行。 如果使用者名稱為 wiley 的攻擊者在 userName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM users
WHERE name = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM users;


這種簡化的查詢會允許攻擊者略過下列要求:查詢必須僅傳回由指定使用者所擁有的使用者;查詢現在會回傳儲存在 users 表格中的所有項目,無論它們的指定使用者是誰。

避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動在 SQL 查詢中避開特殊字元的輸入有一定作用,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。 雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。 儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的陳述式類型。 但是,雖然有許多的限制方法,仍有許多危險的陳述式可以傳入儲存的程序中。 所以再次強調,儲存的程序可以避免部分攻擊,但是並不能完全協助您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[5] IDS00-J. Prevent SQL Injection CERT
[6] INJECT-2: Avoid dynamic SQL Oracle
desc.dataflow.scala.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改陳述式的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1.資料從一個不可信賴的來源進入程式。

2.資料用來動態建構 SQL 查詢。
範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名字的項目。查詢僅會顯示 owner與目前已驗證使用者名稱相符的項目。


...
let queryStatementString = "SELECT * FROM items WHERE owner='\(username)' AND itemname='\(item)'"
var queryStatement: OpaquePointer? = nil
if sqlite3_prepare_v2(db, queryStatementString, -1, &queryStatement, nil) == SQLITE_OK {
if sqlite3_step(queryStatement) == SQLITE_ROW {
...
}
}
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = '<userName>'
AND itemname = '<itemName>'


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在itemName沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a'會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 3:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'); DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開陳述式的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。所以,在此案例中,SQL 查詢中最後的一個單引號將會被作為註釋處理。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動在 SQL 查詢中避開特殊字元的輸入有一定作用,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的陳述式類型。但是,雖然有許多的限制方法,仍有許多危險的陳述式可以傳入儲存的程序中。所以再次強調,儲存的程序可以避免部分攻擊,但是並不能完全協助您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[5] Parameterized CRecordset and CDatabase for SQL Server
[6] Parameterizing a Recordset Microsoft
[7] ODBC API Reference: SQLNumParams() Microsoft
[8] ODBC API Reference: SQLBindParameter() Microsoft
[9] OLE DB Reference: ICommandWithParameters Microsoft
desc.dataflow.swift.sql_injection
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可能會讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。



2. 資料用來動態建構 SQL 查詢。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
username = Session("username")
itemName = Request.Form("itemName")
strSQL = "SELECT * FROM items WHERE owner = '"& userName &"' AND itemname = '" & itemName &"'"
objRecordSet.Open strSQL, strConnect, adOpenDynamic, adLockOptimistic, adCmdText
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存過程在某些情況下可以避免這種攻擊,但是並不能完全保護您的應用系統抵禦 SQL injection 的攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
desc.dataflow.vb.sql_injection
Abstract
透過不可信賴來源的輸入來建立的動態 Castle ActiveRecord 陳述式可能會讓攻擊者修改陳述式的意義或是執行任意的 SQL 指令。
Explanation
與 Castle ActiveRecord 相關的 SQL 注入錯誤會在以下情況下出現:

1. 資料從一個不可信賴的來源進入程式。

2. 此資料將用來動態建構查詢。
範例 1:以下程式碼動態地建構並執行了一個 Castle ActiveRecord 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示 owner 與目前已驗證使用者名稱相符的項目。


...
string userName = ctx.getAuthenticatedUserName();
string queryString = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";

SimpleQuery<Item> queryObject = new SimpleQuery(queryString);
Item[] items = (Item[])queryObject.Execute(query);

...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

避免 Castle ActiveRecord injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 Castle ActiveRecord 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,對於實作拒絕清單方法,總是存在一些漏洞,所以無法有效避免 Castle ActiveRecord SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 Castle ActiveRecord 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 Castle ActiveRecord SQL Injection 攻擊

另外一個處理 Castle ActiveRecord Injection 攻擊的最常建議的方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 Castle ActiveRecord Injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 Castle ActiveRecord SQL Injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存的程序可以避免部分攻擊,但無法保護您的應用程式免於 Castle ActiveRecord Injection 攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[5] Standards Mapping - CIS Azure Kubernetes Service Benchmark 5
[6] Standards Mapping - CIS Microsoft Azure Foundations Benchmark complete
[7] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[8] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[9] Standards Mapping - CIS Google Kubernetes Engine Benchmark integrity
[10] Standards Mapping - CIS Kubernetes Benchmark partial
[11] Standards Mapping - Common Weakness Enumeration CWE ID 89
[12] Standards Mapping - Common Weakness Enumeration Top 25 2019 [6] CWE ID 089
[13] Standards Mapping - Common Weakness Enumeration Top 25 2020 [6] CWE ID 089
[14] Standards Mapping - Common Weakness Enumeration Top 25 2021 [6] CWE ID 089
[15] Standards Mapping - Common Weakness Enumeration Top 25 2022 [3] CWE ID 089
[16] Standards Mapping - Common Weakness Enumeration Top 25 2023 [3] CWE ID 089
[17] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-001310, CCI-002754
[18] Standards Mapping - FIPS200 SI
[19] Standards Mapping - General Data Protection Regulation (GDPR) Indirect Access to Sensitive Data
[20] Standards Mapping - NIST Special Publication 800-53 Revision 4 SI-10 Information Input Validation (P1)
[21] Standards Mapping - NIST Special Publication 800-53 Revision 5 SI-10 Information Input Validation
[22] Standards Mapping - OWASP Top 10 2004 A6 Injection Flaws
[23] Standards Mapping - OWASP Top 10 2007 A2 Injection Flaws
[24] Standards Mapping - OWASP Top 10 2010 A1 Injection
[25] Standards Mapping - OWASP Top 10 2013 A1 Injection
[26] Standards Mapping - OWASP Top 10 2017 A1 Injection
[27] Standards Mapping - OWASP Top 10 2021 A03 Injection
[28] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.3.4 Output Encoding and Injection Prevention Requirements (L1 L2 L3), 5.3.5 Output Encoding and Injection Prevention Requirements (L1 L2 L3)
[29] Standards Mapping - OWASP Mobile 2014 M1 Weak Server Side Controls
[30] Standards Mapping - OWASP Mobile Application Security Verification Standard 2.0 MASVS-CODE-4, MASVS-PLATFORM-1
[31] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 Requirement 6.5.6
[32] Standards Mapping - Payment Card Industry Data Security Standard Version 1.2 Requirement 6.3.1.1, Requirement 6.5.2
[33] Standards Mapping - Payment Card Industry Data Security Standard Version 2.0 Requirement 6.5.1
[34] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.1
[35] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.1
[36] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.1
[37] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.1
[38] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[39] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[40] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation
[41] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation, Control Objective C.3.2 - Web Software Attack Mitigation
[42] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 089
[43] Standards Mapping - SANS Top 25 2010 Insecure Interaction - CWE ID 089
[44] Standards Mapping - SANS Top 25 2011 Insecure Interaction - CWE ID 089
[45] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[46] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[47] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[48] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[49] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[50] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[51] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[52] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[53] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[54] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[55] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[56] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[57] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[58] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[59] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[60] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[61] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[62] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[63] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[64] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[65] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002530 CAT II, APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[66] Standards Mapping - Web Application Security Consortium Version 2.00 SQL Injection (WASC-19)
[67] Standards Mapping - Web Application Security Consortium 24 + 2 SQL Injection
desc.dataflow.dotnet.sql_injection_castleActiveRecord
Abstract
使用 Hibernate 執行透過不可信賴來源的輸入來建立的動態 SQL 陳述式,可能會讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。



2. 此資料將用來動態建構 HQL 查詢。

範例 1:以下程式碼會動態構建並執行一個 HQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
String userName = ctx.getAuthenticatedUserName();
String itemName = request.getParameter("itemName");
String query = "FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ itemName + "'";
List items = sess.createQuery(query).list();
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存的程序可以避免部分盜取情況,但無法保護您的應用程式免於 SQL Injection 攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[5] Hibernate API Documentation
[6] IDS00-J. Prevent SQL Injection CERT
[7] INJECT-2: Avoid dynamic SQL Oracle
[8] Standards Mapping - CIS Azure Kubernetes Service Benchmark 5
[9] Standards Mapping - CIS Microsoft Azure Foundations Benchmark complete
[10] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[11] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[12] Standards Mapping - CIS Google Kubernetes Engine Benchmark integrity
[13] Standards Mapping - CIS Kubernetes Benchmark partial
[14] Standards Mapping - Common Weakness Enumeration CWE ID 564
[15] Standards Mapping - Common Weakness Enumeration Top 25 2019 [6] CWE ID 089
[16] Standards Mapping - Common Weakness Enumeration Top 25 2020 [6] CWE ID 089
[17] Standards Mapping - Common Weakness Enumeration Top 25 2021 [6] CWE ID 089
[18] Standards Mapping - Common Weakness Enumeration Top 25 2022 [3] CWE ID 089
[19] Standards Mapping - Common Weakness Enumeration Top 25 2023 [3] CWE ID 089
[20] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-001310, CCI-002754
[21] Standards Mapping - FIPS200 SI
[22] Standards Mapping - General Data Protection Regulation (GDPR) Indirect Access to Sensitive Data
[23] Standards Mapping - NIST Special Publication 800-53 Revision 4 SI-10 Information Input Validation (P1)
[24] Standards Mapping - NIST Special Publication 800-53 Revision 5 SI-10 Information Input Validation
[25] Standards Mapping - OWASP Top 10 2004 A6 Injection Flaws
[26] Standards Mapping - OWASP Top 10 2007 A2 Injection Flaws
[27] Standards Mapping - OWASP Top 10 2010 A1 Injection
[28] Standards Mapping - OWASP Top 10 2013 A1 Injection
[29] Standards Mapping - OWASP Top 10 2017 A1 Injection
[30] Standards Mapping - OWASP Top 10 2021 A03 Injection
[31] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.3.4 Output Encoding and Injection Prevention Requirements (L1 L2 L3), 5.3.5 Output Encoding and Injection Prevention Requirements (L1 L2 L3)
[32] Standards Mapping - OWASP Mobile 2014 M1 Weak Server Side Controls
[33] Standards Mapping - OWASP Mobile Application Security Verification Standard 2.0 MASVS-CODE-4, MASVS-PLATFORM-1
[34] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 Requirement 6.5.6
[35] Standards Mapping - Payment Card Industry Data Security Standard Version 1.2 Requirement 6.3.1.1, Requirement 6.5.2
[36] Standards Mapping - Payment Card Industry Data Security Standard Version 2.0 Requirement 6.5.1
[37] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.1
[38] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.1
[39] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.1
[40] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.1
[41] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[42] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[43] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation
[44] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation, Control Objective C.3.2 - Web Software Attack Mitigation
[45] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 116
[46] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[47] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[48] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[49] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[50] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[51] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[52] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[53] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[54] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[55] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[56] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[57] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[58] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[59] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[60] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[61] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[62] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[63] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[64] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[65] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[66] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002530 CAT II, APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[67] Standards Mapping - Web Application Security Consortium Version 2.00 SQL Injection (WASC-19)
[68] Standards Mapping - Web Application Security Consortium 24 + 2 SQL Injection
desc.dataflow.java.sql_injection_hibernate
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改陳述式的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1.資料從一個不可信賴的來源進入程式。

2.資料用來動態建構 SQL 查詢。



iBatis Data Map 可讓您指定 SQL 陳述式中的動態參數,並以使用 # 字元來做為典型的定義方式,如下所示:


<select id="getItems" parameterClass="MyClass" resultClass="items">
SELECT * FROM items WHERE owner = #userName#
</select>


變數名稱周圍的 # 字元表示 iBatis 將使用 userName 變數建立參數化查詢。不過,iBatis 也可讓您使用 $ 字元,將變數直接串連至 SQL 陳述式,製造執行 SQL injection 的機會。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名字的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


<select id="getItems" parameterClass="MyClass" resultClass="items">
SELECT * FROM items WHERE owner = #userName# AND itemname = '$itemName$'
</select>


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串 name' OR 'a'='a,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開陳述式的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,一般攻擊者仍然可以使用類似 Example 1 中所示的訣竅進行攻擊。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,對於實作拒絕清單方法,總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的欄位當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動在 SQL 查詢中避開特殊字元的輸入有一定作用,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然預存程序可防止某些類型的 SQL Injection 攻擊,但是對於大多數的攻擊還是無能為力。預存程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳遞到參數的陳述式類型。但是,雖然有許多的限制方法,仍有許多危險的陳述式可以傳入儲存的程序中。所以再次強調,儲存的程序可以避免部分攻擊,但是並不能完全協助您的應用系統抵禦 SQL injection 的攻擊。
References
[1] iBatis Working with Data Maps
[2] iBatis Data Mapper Developer Guide
[3] S. J. Friedl SQL Injection Attacks by Example
[4] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[5] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[6] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[7] IDS00-J. Prevent SQL Injection CERT
[8] Standards Mapping - CIS Azure Kubernetes Service Benchmark 5
[9] Standards Mapping - CIS Microsoft Azure Foundations Benchmark complete
[10] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 4
[11] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[12] Standards Mapping - CIS Google Kubernetes Engine Benchmark integrity
[13] Standards Mapping - CIS Kubernetes Benchmark partial
[14] Standards Mapping - Common Weakness Enumeration CWE ID 89
[15] Standards Mapping - Common Weakness Enumeration Top 25 2019 [6] CWE ID 089
[16] Standards Mapping - Common Weakness Enumeration Top 25 2020 [6] CWE ID 089
[17] Standards Mapping - Common Weakness Enumeration Top 25 2021 [6] CWE ID 089
[18] Standards Mapping - Common Weakness Enumeration Top 25 2022 [3] CWE ID 089
[19] Standards Mapping - Common Weakness Enumeration Top 25 2023 [3] CWE ID 089
[20] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-001310, CCI-002754
[21] Standards Mapping - FIPS200 SI
[22] Standards Mapping - General Data Protection Regulation (GDPR) Indirect Access to Sensitive Data
[23] Standards Mapping - NIST Special Publication 800-53 Revision 4 SI-10 Information Input Validation (P1)
[24] Standards Mapping - NIST Special Publication 800-53 Revision 5 SI-10 Information Input Validation
[25] Standards Mapping - OWASP Top 10 2004 A6 Injection Flaws
[26] Standards Mapping - OWASP Top 10 2007 A2 Injection Flaws
[27] Standards Mapping - OWASP Top 10 2010 A1 Injection
[28] Standards Mapping - OWASP Top 10 2013 A1 Injection
[29] Standards Mapping - OWASP Top 10 2017 A1 Injection
[30] Standards Mapping - OWASP Top 10 2021 A03 Injection
[31] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.3.4 Output Encoding and Injection Prevention Requirements (L1 L2 L3), 5.3.5 Output Encoding and Injection Prevention Requirements (L1 L2 L3)
[32] Standards Mapping - OWASP Mobile 2014 M1 Weak Server Side Controls
[33] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 Requirement 6.5.6
[34] Standards Mapping - Payment Card Industry Data Security Standard Version 1.2 Requirement 6.3.1.1, Requirement 6.5.2
[35] Standards Mapping - Payment Card Industry Data Security Standard Version 2.0 Requirement 6.5.1
[36] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.1
[37] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.1
[38] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.1
[39] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.1
[40] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[41] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[42] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation
[43] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation, Control Objective C.3.2 - Web Software Attack Mitigation
[44] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 089
[45] Standards Mapping - SANS Top 25 2010 Insecure Interaction - CWE ID 089
[46] Standards Mapping - SANS Top 25 2011 Insecure Interaction - CWE ID 089
[47] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[48] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[49] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[50] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[51] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[52] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[53] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[54] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[55] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[56] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[57] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[58] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[59] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[60] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[61] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[62] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[63] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[64] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[65] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[66] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[67] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002530 CAT II, APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[68] Standards Mapping - Web Application Security Consortium Version 2.00 SQL Injection (WASC-19)
[69] Standards Mapping - Web Application Security Consortium 24 + 2 SQL Injection
desc.config.java.sql_injection_ibatis_data_map
Abstract
使用 Java Data Objects (JDO) 執行透過不可信賴來源的輸入建立的動態 SQL 或 JDOQL 指令,可能會讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1. 資料從一個不可信賴的來源進入程式。



2. 資料用來動態建構 SQL 或 JDOQL 查詢。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名稱的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


...
String userName = ctx.getAuthenticatedUserName();
String itemName = request.getParameter("itemName");
String sql = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ itemName + "'";
Query query = pm.newQuery(Query.SQL, sql);
query.setClass(Person.class);
List people = (List)query.execute();
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,實作拒絕清單總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 SQL 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 SQL injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存的程序可以避免部分盜取情況,但無法保護您的應用程式免於 SQL Injection 攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[5] JDO API Documentation
[6] IDS00-J. Prevent SQL Injection CERT
[7] INJECT-2: Avoid dynamic SQL Oracle
[8] Standards Mapping - CIS Azure Kubernetes Service Benchmark 5
[9] Standards Mapping - CIS Microsoft Azure Foundations Benchmark complete
[10] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[11] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[12] Standards Mapping - CIS Google Kubernetes Engine Benchmark integrity
[13] Standards Mapping - CIS Kubernetes Benchmark partial
[14] Standards Mapping - Common Weakness Enumeration CWE ID 89
[15] Standards Mapping - Common Weakness Enumeration Top 25 2019 [6] CWE ID 089
[16] Standards Mapping - Common Weakness Enumeration Top 25 2020 [6] CWE ID 089
[17] Standards Mapping - Common Weakness Enumeration Top 25 2021 [6] CWE ID 089
[18] Standards Mapping - Common Weakness Enumeration Top 25 2022 [3] CWE ID 089
[19] Standards Mapping - Common Weakness Enumeration Top 25 2023 [3] CWE ID 089
[20] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-001310, CCI-002754
[21] Standards Mapping - FIPS200 SI
[22] Standards Mapping - General Data Protection Regulation (GDPR) Indirect Access to Sensitive Data
[23] Standards Mapping - NIST Special Publication 800-53 Revision 4 SI-10 Information Input Validation (P1)
[24] Standards Mapping - NIST Special Publication 800-53 Revision 5 SI-10 Information Input Validation
[25] Standards Mapping - OWASP Top 10 2004 A6 Injection Flaws
[26] Standards Mapping - OWASP Top 10 2007 A2 Injection Flaws
[27] Standards Mapping - OWASP Top 10 2010 A1 Injection
[28] Standards Mapping - OWASP Top 10 2013 A1 Injection
[29] Standards Mapping - OWASP Top 10 2017 A1 Injection
[30] Standards Mapping - OWASP Top 10 2021 A03 Injection
[31] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.3.4 Output Encoding and Injection Prevention Requirements (L1 L2 L3), 5.3.5 Output Encoding and Injection Prevention Requirements (L1 L2 L3)
[32] Standards Mapping - OWASP Mobile 2014 M1 Weak Server Side Controls
[33] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 Requirement 6.5.6
[34] Standards Mapping - Payment Card Industry Data Security Standard Version 1.2 Requirement 6.3.1.1, Requirement 6.5.2
[35] Standards Mapping - Payment Card Industry Data Security Standard Version 2.0 Requirement 6.5.1
[36] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.1
[37] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.1
[38] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.1
[39] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.1
[40] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[41] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[42] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation
[43] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation, Control Objective C.3.2 - Web Software Attack Mitigation
[44] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 089
[45] Standards Mapping - SANS Top 25 2010 Insecure Interaction - CWE ID 089
[46] Standards Mapping - SANS Top 25 2011 Insecure Interaction - CWE ID 089
[47] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[48] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[49] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[50] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[51] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[52] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[53] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[54] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[55] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[56] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[57] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[58] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[59] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[60] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[61] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[62] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[63] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[64] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[65] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[66] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[67] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002530 CAT II, APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[68] Standards Mapping - Web Application Security Consortium Version 2.00 SQL Injection (WASC-19)
[69] Standards Mapping - Web Application Security Consortium 24 + 2 SQL Injection
desc.dataflow.java.sql_injection_jdo
Abstract
透過不可信賴來源的輸入來建立的動態 LINQ 陳述式可能會讓攻擊者修改指令的意義或是執行任意的 SQL 指令。
Explanation
下列情況下會發生與 LINQ 有關的注入錯誤:

1. 資料從一個不可信賴的來源進入程式。

2. 此資料將用來動態建構查詢。
範例 1:以下程式碼動態地建構並執行 LINQ 查詢,以搜尋符合指定名稱的項目。查詢僅會顯示 owner 與目前已驗證使用者名稱相符的項目。


...
string userName = ctx.getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";

var items = dataContext.ExecuteCommand<Item>(query);
...


此查詢欲執行以下程式碼:


SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name' OR 'a'='a」,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


附加條件 OR 'a'='a' 會使 where 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢必須只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'); DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開指令的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,攻擊者通常會使用類似 Example 1 中的方法。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 LINQ injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 LINQ 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,對於實作拒絕清單方法,總是存在一些漏洞,所以無法有效避免 LINQ injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的值當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動去除在 LINQ 查詢中特殊字元的輸入有一定的幫助,但無法完全保護您的應用程式免於 LINQ Injection 攻擊。

另外一個處理 LINQ Injection 攻擊的普遍建議方法為使用儲存的程序。雖然儲存的程序可避免某些類型的 LINQ Injection 攻擊,但是對於大多數的攻擊還是無能為力。儲存的程序一般用來避免 LINQ Injection 攻擊的方式是,限制可以傳送到參數的指令類型。但是,雖然有許多的限制方法,仍有許多危險的指令可以傳入儲存的程序中。所以再次強調,儲存的程序可以避免部分攻擊情況,但無法保護您的應用程式免於 LINQ Injection 攻擊。
References
[1] S. J. Friedl SQL Injection Attacks by Example
[2] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[3] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[4] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[5] Standards Mapping - CIS Azure Kubernetes Service Benchmark 5
[6] Standards Mapping - CIS Microsoft Azure Foundations Benchmark complete
[7] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5
[8] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[9] Standards Mapping - CIS Google Kubernetes Engine Benchmark integrity
[10] Standards Mapping - CIS Kubernetes Benchmark partial
[11] Standards Mapping - Common Weakness Enumeration CWE ID 89
[12] Standards Mapping - Common Weakness Enumeration Top 25 2019 [6] CWE ID 089
[13] Standards Mapping - Common Weakness Enumeration Top 25 2020 [6] CWE ID 089
[14] Standards Mapping - Common Weakness Enumeration Top 25 2021 [6] CWE ID 089
[15] Standards Mapping - Common Weakness Enumeration Top 25 2022 [3] CWE ID 089
[16] Standards Mapping - Common Weakness Enumeration Top 25 2023 [3] CWE ID 089
[17] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-001310, CCI-002754
[18] Standards Mapping - FIPS200 SI
[19] Standards Mapping - General Data Protection Regulation (GDPR) Indirect Access to Sensitive Data
[20] Standards Mapping - NIST Special Publication 800-53 Revision 4 SI-10 Information Input Validation (P1)
[21] Standards Mapping - NIST Special Publication 800-53 Revision 5 SI-10 Information Input Validation
[22] Standards Mapping - OWASP Top 10 2004 A6 Injection Flaws
[23] Standards Mapping - OWASP Top 10 2007 A2 Injection Flaws
[24] Standards Mapping - OWASP Top 10 2010 A1 Injection
[25] Standards Mapping - OWASP Top 10 2013 A1 Injection
[26] Standards Mapping - OWASP Top 10 2017 A1 Injection
[27] Standards Mapping - OWASP Top 10 2021 A03 Injection
[28] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.3.4 Output Encoding and Injection Prevention Requirements (L1 L2 L3), 5.3.5 Output Encoding and Injection Prevention Requirements (L1 L2 L3)
[29] Standards Mapping - OWASP Mobile 2014 M7 Client Side Injection
[30] Standards Mapping - OWASP Mobile Application Security Verification Standard 2.0 MASVS-CODE-4
[31] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 Requirement 6.5.6
[32] Standards Mapping - Payment Card Industry Data Security Standard Version 1.2 Requirement 6.3.1.1, Requirement 6.5.2
[33] Standards Mapping - Payment Card Industry Data Security Standard Version 2.0 Requirement 6.5.1
[34] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.1
[35] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.1
[36] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.1
[37] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.1
[38] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[39] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[40] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation
[41] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation, Control Objective C.3.2 - Web Software Attack Mitigation
[42] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 089
[43] Standards Mapping - SANS Top 25 2010 Insecure Interaction - CWE ID 089
[44] Standards Mapping - SANS Top 25 2011 Insecure Interaction - CWE ID 089
[45] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[46] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[47] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[48] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[49] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[50] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[51] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[52] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[53] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[54] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[55] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[56] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[57] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[58] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[59] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[60] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[61] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[62] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[63] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[64] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[65] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002530 CAT II, APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[66] Standards Mapping - Web Application Security Consortium Version 2.00 SQL Injection (WASC-19)
[67] Standards Mapping - Web Application Security Consortium 24 + 2 SQL Injection
desc.dataflow.dotnet.sql_injection_linq
Abstract
透過不可信賴來源的輸入來建構的動態 SQL 陳述式可讓攻擊者修改陳述式的意義或是執行任意的 SQL 指令。
Explanation
SQL Injection 錯誤會在以下情況中出現:

1.資料從一個不可信賴的來源進入程式。

2.資料用來動態建構 SQL 查詢。



MyBatis Mapper XML 檔案可讓您指定 SQL 陳述式中的動態參數,並使用 # 字元來進行典型定義,如下所示:


<select id="getItems" parameterType="domain.company.MyParamClass" resultType="MyResultMap">
SELECT *
FROM items
WHERE owner = #{userName}
</select>


用括號括住變數名稱的 # 字元表示 MyBatis 將使用 userName 變數建立參數化查詢。不過,MyBatis 也可讓您使用 $ 字元,將變數直接串連至 SQL 陳述式,製造執行 SQL injection 的機會。

範例 1:以下程式碼動態地建構並執行了一個 SQL 查詢,該查詢可用來搜尋符合指定名字的項目。查詢僅會顯示項目所有者與目前已驗證使用者名稱相符的項目。


<select id="getItems" parameterType="domain.company.MyParamClass" resultType="MyResultMap">
SELECT *
FROM items
WHERE owner = #{userName}
AND itemname = ${itemName}
</select>


但是,由於這個查詢是連續固定基礎查詢字串和使用者輸入字串所動態建構而成的,所以只有在 itemName 沒有包含單引號字元的時候,查詢才會正確執行。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串 name' OR 'a'='a,那麼查詢將變成以下內容:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';


加上 OR 'a'='a' 條件會使 WHERE 子句的評估永遠為 True,所以此查詢在邏輯上可等同於以下較簡化的查詢:


SELECT * FROM items;


由於查詢理應只會傳回驗證使用者所擁有的項目,但簡化查詢會讓攻擊者不再受到此要求所限制;因此,查詢現在將會傳回所有儲存在 items 表中的項目,而不考慮指定的擁有者為何。

範例 2:此範例會檢查不同的惡意值傳送到建立的查詢以及在 Example 1 中執行的效果。如果使用者名稱為 wiley 的攻擊者在 itemName 中輸入字串「name'; DELETE FROM items; --」,那麼查詢將變成以下兩個查詢:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

--'


許多的資料庫伺服器 (包括 Microsoft(R) SQL Server 2000),允許一次執行多個由分號隔開的 SQL 陳述式。此攻擊字串會在 Oracle 和其他不允許整批執行由分號隔開陳述式的資料庫伺服器上造成錯誤,而在允許整批執行的資料庫上,此類的攻擊可讓攻擊者對資料庫執行任意的指令。

請注意這對連字符號 (--),這在大部分的資料庫伺服器上都表示剩餘的陳述式,並視為註釋不予執行 [4]。在此案例中,註釋字元會從修改的查詢中將剩餘的一個單引號移除。在不允許以此方式使用註釋的資料庫中,一般攻擊者仍然可以使用類似 Example 1 中所示的訣竅進行攻擊。如果攻擊者輸入「name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a」字串,將會建立以下三個有效的陳述式:


SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';

DELETE FROM items;

SELECT * FROM items WHERE 'a'='a';


避免 SQL injection 攻擊的一個傳統方法為,將其視為輸入驗證的問題,只接受安全值允許清單中的字元,或是驗證並避免來自潛在惡意值的清單 (拒絕清單)。檢查允許清單是一種相當有效的方法,可強制執行嚴格的輸入驗證規則,而參數化 SQL 陳述式所需的維護較少,並且能提供更高的安全性保障。通常,對於實作拒絕清單方法,總是存在一些漏洞,所以無法有效避免 SQL injection 攻擊。例如,攻擊者可能:

- 將未列入黑名單的欄位當作目標
- 尋找方法以略過特定逸出中繼字元 (escape meta-character) 的需要
- 使用儲存的程序去隱藏插入的中繼字元

手動逸出在 SQL 查詢中字元的輸入有一定的幫助,但無法保證應用程式能免於 SQL injection 攻擊。

另外一個處理 SQL injection 攻擊的普遍建議方法為使用儲存的程序。雖然預存程序可防止某些類型的 SQL Injection 攻擊,但是對於大多數的攻擊還是無能為力。預存程序一般用來避免 SQL injection 攻擊的方式是,限制可以傳遞到參數的陳述式類型。但是,雖然有許多的限制方法,仍有許多危險的陳述式可以傳入儲存的程序中。所以再次強調,儲存的程序可以避免部分攻擊,但是並不能完全協助您的應用系統抵禦 SQL injection 的攻擊。
References
[1] MyBatis MyBatis 3 | Mapper XML Files
[2] MyBatis MyBatis 3 | Dynamic SQL
[3] S. J. Friedl SQL Injection Attacks by Example
[4] P. Litwin Stop SQL Injection Attacks Before They Stop You MSDN Magazine
[5] P. Finnigan SQL Injection and Oracle, Part One Security Focus
[6] M. Howard, D. LeBlanc Writing Secure Code, Second Edition Microsoft Press
[7] IDS00-J. Prevent SQL Injection CERT
[8] INJECT-2: Avoid dynamic SQL Oracle
[9] Standards Mapping - CIS Azure Kubernetes Service Benchmark 5
[10] Standards Mapping - CIS Microsoft Azure Foundations Benchmark complete
[11] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 4
[12] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[13] Standards Mapping - CIS Google Kubernetes Engine Benchmark integrity
[14] Standards Mapping - CIS Kubernetes Benchmark partial
[15] Standards Mapping - Common Weakness Enumeration CWE ID 89
[16] Standards Mapping - Common Weakness Enumeration Top 25 2019 [6] CWE ID 089
[17] Standards Mapping - Common Weakness Enumeration Top 25 2020 [6] CWE ID 089
[18] Standards Mapping - Common Weakness Enumeration Top 25 2021 [6] CWE ID 089
[19] Standards Mapping - Common Weakness Enumeration Top 25 2022 [3] CWE ID 089
[20] Standards Mapping - Common Weakness Enumeration Top 25 2023 [3] CWE ID 089
[21] Standards Mapping - DISA Control Correlation Identifier Version 2 CCI-001310, CCI-002754
[22] Standards Mapping - FIPS200 SI
[23] Standards Mapping - General Data Protection Regulation (GDPR) Indirect Access to Sensitive Data
[24] Standards Mapping - NIST Special Publication 800-53 Revision 4 SI-10 Information Input Validation (P1)
[25] Standards Mapping - NIST Special Publication 800-53 Revision 5 SI-10 Information Input Validation
[26] Standards Mapping - OWASP Top 10 2004 A6 Injection Flaws
[27] Standards Mapping - OWASP Top 10 2007 A2 Injection Flaws
[28] Standards Mapping - OWASP Top 10 2010 A1 Injection
[29] Standards Mapping - OWASP Top 10 2013 A1 Injection
[30] Standards Mapping - OWASP Top 10 2017 A1 Injection
[31] Standards Mapping - OWASP Top 10 2021 A03 Injection
[32] Standards Mapping - OWASP Application Security Verification Standard 4.0 5.3.4 Output Encoding and Injection Prevention Requirements (L1 L2 L3), 5.3.5 Output Encoding and Injection Prevention Requirements (L1 L2 L3)
[33] Standards Mapping - OWASP Mobile 2014 M1 Weak Server Side Controls
[34] Standards Mapping - OWASP Mobile Application Security Verification Standard 2.0 MASVS-CODE-4, MASVS-PLATFORM-1
[35] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 Requirement 6.5.6
[36] Standards Mapping - Payment Card Industry Data Security Standard Version 1.2 Requirement 6.3.1.1, Requirement 6.5.2
[37] Standards Mapping - Payment Card Industry Data Security Standard Version 2.0 Requirement 6.5.1
[38] Standards Mapping - Payment Card Industry Data Security Standard Version 3.0 Requirement 6.5.1
[39] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2 Requirement 6.5.1
[40] Standards Mapping - Payment Card Industry Data Security Standard Version 3.2.1 Requirement 6.5.1
[41] Standards Mapping - Payment Card Industry Data Security Standard Version 3.1 Requirement 6.5.1
[42] Standards Mapping - Payment Card Industry Data Security Standard Version 4.0 Requirement 6.2.4
[43] Standards Mapping - Payment Card Industry Software Security Framework 1.0 Control Objective 4.2 - Critical Asset Protection
[44] Standards Mapping - Payment Card Industry Software Security Framework 1.1 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation
[45] Standards Mapping - Payment Card Industry Software Security Framework 1.2 Control Objective 4.2 - Critical Asset Protection, Control Objective B.3.1 - Terminal Software Attack Mitigation, Control Objective B.3.1.1 - Terminal Software Attack Mitigation, Control Objective C.3.2 - Web Software Attack Mitigation
[46] Standards Mapping - SANS Top 25 2009 Insecure Interaction - CWE ID 089
[47] Standards Mapping - SANS Top 25 2010 Insecure Interaction - CWE ID 089
[48] Standards Mapping - SANS Top 25 2011 Insecure Interaction - CWE ID 089
[49] Standards Mapping - Security Technical Implementation Guide Version 3.1 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[50] Standards Mapping - Security Technical Implementation Guide Version 3.4 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[51] Standards Mapping - Security Technical Implementation Guide Version 3.5 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[52] Standards Mapping - Security Technical Implementation Guide Version 3.6 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[53] Standards Mapping - Security Technical Implementation Guide Version 3.7 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[54] Standards Mapping - Security Technical Implementation Guide Version 3.9 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[55] Standards Mapping - Security Technical Implementation Guide Version 3.10 APP3510 CAT I, APP3540.1 CAT I, APP3540.3 CAT II
[56] Standards Mapping - Security Technical Implementation Guide Version 4.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[57] Standards Mapping - Security Technical Implementation Guide Version 4.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[58] Standards Mapping - Security Technical Implementation Guide Version 4.3 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[59] Standards Mapping - Security Technical Implementation Guide Version 4.4 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[60] Standards Mapping - Security Technical Implementation Guide Version 4.5 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[61] Standards Mapping - Security Technical Implementation Guide Version 4.6 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[62] Standards Mapping - Security Technical Implementation Guide Version 4.7 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[63] Standards Mapping - Security Technical Implementation Guide Version 4.8 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[64] Standards Mapping - Security Technical Implementation Guide Version 4.9 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[65] Standards Mapping - Security Technical Implementation Guide Version 4.10 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[66] Standards Mapping - Security Technical Implementation Guide Version 4.11 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[67] Standards Mapping - Security Technical Implementation Guide Version 5.1 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[68] Standards Mapping - Security Technical Implementation Guide Version 5.2 APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[69] Standards Mapping - Security Technical Implementation Guide Version 5.3 APSC-DV-002530 CAT II, APSC-DV-002540 CAT I, APSC-DV-002560 CAT I
[70] Standards Mapping - Web Application Security Consortium Version 2.00 SQL Injection (WASC-19)
[71] Standards Mapping - Web Application Security Consortium 24 + 2 SQL Injection
desc.config.java.sql_injection_mybatis_mapper