계: 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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]. 이 경우, 이 주석 문자는 수정된 쿼리에서 마지막의 작은따옴표 한쪽을 제거하는 역할을 합니다. 주석을 이런 식으로 사용할 수 없는 데이터베이스에서도 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어 공격자는 다음과 같은 작업을 수행할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL Injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL Injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(Stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL Injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 다시 말해, 저장 프로시저(Stored procedure)는 일부 유형의 악용은 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL Injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL Injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(Stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL Injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 다시 말해, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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';


모바일 환경에서는 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 이상의 예제에서 보듯이 저장 프로시저(stored procedure)도 다른 코드와 마찬가지로 취약합니다. 저장 프로시저(stored procedure)는 일정 유형의 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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가 실제로 숫자인지 검사하지 않기 때문에 공격자가 id 값을 1 OR id!=1--로 변경할 수 있다면 이제 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이거나 1이 아닌 모든 것을 선택하는데 이는 당연히 테이블 내의 모든 것에 해당합니다.

많은 데이터베이스 서버에서 여러 SQL 문을 세미콜론으로 구분하여 한꺼번에 실행하는 것을 허용합니다. 이 공격 문자열은 세미콜론으로 구분한 문에 대한 일괄 실행을 허용하지 않는 Oracle 및 기타 데이터베이스 서버에서는 오류를 일으키지만 일괄 실행을 허용하는 데이터베이스에서는 공격자가 이런 종류의 공격으로 데이터베이스에 대해 임의의 명령을 실행할 수 있습니다.

SQL Injection 공격을 방지하는 한 가지 기존의 접근 방식은 공격을 입력값 검증 문제로 처리하고 안전한 값 목록(허용 목록)의 문자만 받거나 악의적일 가능성이 있는 값 목록(거부 목록)을 식별하여 이스케이프 처리하는 것입니다. 허용 목록 검사는 엄격한 입력값 검증 규칙을 이행하는 매우 효율적인 수단이 되기도 하지만, 매개 변수가 있는 SQL 문은 유지 관리가 쉽고 보다 강력한 보안을 제공할 수 있습니다. 대부분의 경우 거부 목록 구현은 SQL Injection 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL Injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL Injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(Stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL Injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL Injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 다시 말해, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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]. 이 경우, 이 주석 문자는 수정된 쿼리에서 마지막의 작은따옴표 한쪽을 제거하는 역할을 합니다. 주석을 이런 식으로 사용할 수 없는 데이터베이스에서도 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL Injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL Injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(Stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL Injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL Injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 다시 말해, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 injection 오류는 다음 경우에 발생합니다.

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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

Castle ActiveRecord 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 Castle ActiveRecord SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

Castle ActiveRecord injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 Castle ActiveRecord injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 Castle ActiveRecord SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트 유형은 막을 수 있지만 응용 프로그램을 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 문에서 동적 매개변수를 지정할 수 있으며 일반적으로 iBatis Data Map은 다음과 같이 # 문자를 사용하여 정의됩니다.


<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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL Injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL Injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(Stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL Injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 다시 말해, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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
JDO(Java Data Objects)를 사용하여 신뢰할 수 없는 소스에서 나온 입력으로 만들어진 동적 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

SQL injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트 유형은 막을 수 있지만 응용 프로그램을 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와 관련된 Injection 오류는 다음 경우에 발생합니다.

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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

LINQ 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 LINQ injection 공격으로부터 응용 프로그램을 보호할 수는 없습니다.

LINQ injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 LINQ injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 LINQ 문의 유형을 제한하여 LINQ injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 되풀이하지만, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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 공격 방지의 효과를 떨어뜨리는 허점이 아주 많습니다. 예를 들어, 공격자는 다음과 같이 할 수 있습니다.

- 따옴표로 묶지 않은 필드를 노립니다.
- 이스케이프 처리된 메타 문자를 사용할 필요가 없는 방법을 찾습니다.
- 저장 프로시저(Stored procedure)를 사용하여 삽입된 메타 문자를 숨깁니다.

SQL 쿼리에 입력할 때 수동으로 문자를 이스케이프 처리하는 방법도 있지만 이것으로 SQL Injection 공격으로부터 응용 프로그램이 안전하다고 보장할 수는 없습니다.

SQL Injection 공격을 다루는 데 주로 제시되는 다른 솔루션은 저장 프로시저(Stored procedure)를 사용하는 것입니다. 저장 프로시저(Stored procedure)는 일부 유형의 SQL injection 공격은 막을 수 있지만 다른 많은 유형은 막지 못합니다. 저장 프로시저(Stored procedure)는 일반적으로 매개 변수에 전달되는 SQL 문의 유형을 제한하여 SQL Injection 공격을 막습니다. 하지만 이 제약을 피할 수 있는 많은 방법이 있어 수많은 비정상적인 문을 저장 프로시저(Stored procedure)에 전달할 수 있습니다. 다시 말해, 저장 프로시저(Stored procedure)는 일부 익스플로이트는 막을 수 있지만 응용 프로그램을 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