.NET General2006. 7. 22. 02:29

1. SQL Injection 이란?


a. SQL Injection은 SQL 쿼리에 사용되는 사용자의 입력값에 대해서 제대로 유효성 검사를 하지 않았거나 타입 체크를 하지 않아서, 쿼리가 제대로 동작하지 않거나 시스템에 문제를 일으킬 수 있는 다른 코드가 실행될 수 있게 만드는 애플리케이션 상의 보안 취약점이다.



2. SQL Injection의 예


a. 사용자 정보가 DB에 있으며, 로그인 페이지에서 다음과 같은 쿼리를 호출해서 인증을 처리한다고 생각해보자

SELECT * FROM USERS WHERE USERID = '" + UserIDTextBoxValue + "' AND PASSWORD = '" + PasswordTextBoxValue + "'"


b. 여기서 UserIDTextBoxValue에 a' or 1=1 -- 이라는 값을 넣는다면, or 1=1 부분에 의해서 참이 되고, -- 에 의해서 그 다음부터는 주석처리가 되기 때문에 전혀 쿼리에 영향을 주지 않는다. 그러므로, 실제로 실행되는 쿼리는 다음과 같다.

SELECT * FROM USERS WHERE USERID = 'a' or 1=1 -- AND PASSWORD = ''


3. 해결책


a. ADO.NET에서 제공하는 SqlCommand, SqlParameter 객체를 사용하면, 이 SQL Injection 공격으로부터 안전한 코드를 작성할 수 있다. SqlParameter 객체를 통해서 전달된 값은 쿼리 자체에 영향을 끼치지 못하고 문자열로만 취급되기 때문이다. 즉, 위의 쿼리에 Parameter로 a or 1=1 -- 이란 값을 넣어도 'a or 1=1 --" 이라는 문자열과 USERID를 비교하게 되기 때문에 일치하는 값이 없는 것으로 결과가 나오게 될 것이다. 이런 방식을 Parameterized Query라고 한다.

//SqlCommand 객체 생성
System.Data.SqlClient.SqlCommand oCom = new System.Data.SqlClient.SqlCommand();
oCom.CommandText = "SELECT * FROM USERS WHERE USERID = @param1";
oCom.CommandType = CommandType.Text;

//SqlParameter 객체 생성
System.Data.SqlClient.SqlParameter oParam = new System.Data.SqlClient.SqlParameter();
oParam.DbType = DbType.String;
oParam.Value = "value";
oParam.ParameterName = "param1";

//SqlCommand객체에 SqlParameter를 적용한다.
oCom.Parameters.Add(oParam);


b. Stored Procedure를 사용하게 되면 반드시 SqlParameter객체를 사용해야 하기 때문에 Sql Injection으로부터 안전할 수 있다.


c. 하지만 Stored Procedure 내부에서 문자열과 파라미터를 더해서 쿼리를 구성한다면, SQL Injection에 취약한 코드가 된다. 그래서, 이런 Dynamic Query로 이루어진 Stored procedure를 사용할 때는, 아주 엄격하게 Validation을 해야 할 것이다.

Posted by kkongchi