입력 검증 및 표현 문제는 메타 문자, 대체 인코딩 및 숫자 표현 때문에 발생합니다. 보안 문제는 입력을 신뢰하기 때문에 발생합니다. 문제로는 "Buffer Overflows", "Cross-Site Scripting" 공격, "SQL Injection", 그 외 여러 가지가 있습니다.
owner
가 일치하는 항목만 표시하도록 제한합니다.
...
string userName = ctx.GetAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";
List items = sess.CreateSQLQuery(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
테이블에 저장된 모든 항목을 반환합니다.Example 1
에서 생성하여 수행한 쿼리에 또 다른 악성 값이 전달될 때의 결과를 검토합니다. 사용자 이름이 wiley
인 공격자가 ItemName
에 문자열 "name'; DELETE FROM items; --
"를 입력하면 쿼리는 다음과 같은 두 개의 쿼리가 됩니다.
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
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';
owner
가 현재 인증된 사용자의 이름과 일치하는 항목으로 제한합니다.
...
string userName = identity.User;
string itemName = apiGatewayProxyRequest.QueryStringParameters['item'];
string statement = $"SELECT * FROM items WHERE owner = '{userName}' AND itemname = '{itemName}'";
var executeStatementRequest = new ExecuteStatementRequest();
executeStatementRequest.Statement = statement;
var executeStatementResponse = await dynamoDBClient.ExecuteStatementAsync(executeStatementRequest);
return displayResults(executeStatementResponse.Items);
...
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로 평가되기 때문에 쿼리는 훨씬 단순한 다음 쿼리와 논리적으로 동일하게 됩니다.owner
가 현재 인증된 사용자의 이름과 일치하는 항목으로 제한합니다.
...
String userName = identity.getUser();
String itemName = apiGatewayProxyRequest.getQueryStringParameters('item');
String statement = String.format("SELECT * FROM items WHERE owner = '%s' AND itemname = '%s'", userName, itemName);
ExecuteStatementRequest executeStatementRequest = new ExecuteStatementRequest();
executeStatementRequest.setStatement(statement);
ExecuteStatementResponse executeStatementResponse = dynamoDBClient.executeStatement(executeStatementRequest);
return displayResults(executeStatementResponse.items());
...
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로 평가되기 때문에 쿼리는 훨씬 단순한 다음 쿼리와 논리적으로 동일하게 됩니다.
...
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
테이블에 저장된 모든 항목을 반환합니다.Example 1
에서 생성하여 수행한 쿼리에 또 다른 악성 값이 전달될 때의 결과를 검토합니다. 사용자 이름이 wiley
인 공격자가 itemName
에 문자열 "name'; DELETE FROM items; --
"를 입력하면 쿼리는 다음과 같은 두 개의 쿼리가 됩니다.
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
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';
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);
...
mysql_real_escape_string()
같은 인코딩 함수를 사용하면 일부 SQL Injection 취약점이 방지되지만 전부 방지되지는 않습니다. 이러한 인코딩 함수를 사용하는 것은 약한 거부 목록을 사용하여 SQL Injection을 차단하는 것과 동일하며 공격자가 문의 의미를 수정하거나 임의의 SQL 명령을 실행하는 것이 가능할 수 있습니다. 동적으로 해석되는 코드의 지정된 섹션 내에서 입력이 표시되는 위치를 정적으로 확인하는 것이 항상 가능하지는 않으므로 Fortify Secure Coding Rulepacks는 해당 컨텍스트 내에서 검증을 통해 충분히 SQL Injection을 차단할 수 있는 경우에도 검증된 동적 SQL 데이터를 "SQL Injection: Poor Validation" 이슈로 표시할 수 있습니다.mysqli_real_escape_string()
의 동작을 보여줍니다. SQL 모드가 "NO_BACKSLASH_ESCAPES"로 설정된 경우 백슬래시 문자가 이스케이프 문자[5]가 아닌 일반 문자로 처리됩니다. mysqli_real_escape_string()
은 이를 고려하므로 다음 쿼리는 SQL Injection에 취약해집니다. 데이터베이스 구성으로 인해 "
가 더 이상 \"
로 이스케이프 처리되지 않기 때문입니다.
mysqli_query($mysqli, 'SET SQL_MODE="NO_BACKSLASH_ESCAPES"');
...
$userName = mysqli_real_escape_string($mysqli, $_POST['userName']);
$pass = mysqli_real_escape_string($mysqli, $_POST['pass']);
$query = 'SELECT * FROM users WHERE userName="' . $userName . '"AND pass="' . $pass. '";';
$result = mysqli_query($mysqli, $query);
...
password
필드를 비워 두고 " OR 1=1;--
을 userName
으로 입력하면 따옴표가 이스케이프 처리되지 않고 다음과 같은 쿼리가 생성됩니다.
SELECT * FROM users
WHERE userName = ""
OR 1=1;
-- "AND pass="";
OR 1=1
로 인해 where 절이 항상 true로 평가되고 하이픈 두 개로 인해 나머지 문이 주석으로 처리되므로 이 쿼리는 훨씬 더 단순한 쿼리와 논리적으로 동일해집니다.
SELECT * FROM users;
owner
가 일치하는 항목만 표시하도록 제한합니다.
...
string userName = ctx.getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";
IDataReader responseReader = new InlineQuery().ExecuteReader(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
테이블에 저장된 모든 항목을 반환합니다.Example 1
에서 생성하여 수행한 쿼리에 또 다른 악성 값이 전달될 때의 결과를 검토합니다. 사용자 이름이 wiley
인 공격자가 itemName
에 문자열 "name'); DELETE FROM items; --
"를 입력하면 쿼리는 다음과 같은 두 개의 쿼리가 됩니다.
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
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';