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을 해야 할 것이다.
'.NET General' 카테고리의 다른 글
[Etc]MS - PHP - Linux Alliance? (11) | 2006.11.03 |
---|---|
[HowTo]FxCOP(비주얼 스튜디오 2005 코드 분석) Custom 규칙 작성하기(C#) (0) | 2006.07.25 |
[Tip]Visual Studio 2005에서 직접 실행 창을 보이게 하는 방법 (2) | 2006.05.04 |
[Etc]MCPD Beta Exam (0) | 2006.03.05 |
[HowTo]NANT 사용하기 (0) | 2006.02.20 |