SQL Injection이란?
사용자의 입력 값으로 웹 사이트 SQL 쿼리가 완성되는 약점을 이용하며, 입력 값을 변조하여 비정상적인 SQL 쿼리를 조합하거나 실행하는 공격을 말한다. 개발자가 생각지 못한 SQL문을 실행되게 함으로써 데이터베이스를 비정상적으로 조작 가능하다.
SQL Injection 점검
점검 내용 | 웹페이지 내 SQL 인젝션 취약점 존재 여부 점검 |
점검 목적 | 대화형 웹 사이트에 비정상적인 사용자 입력 값 허용을 차단하여 악의적인 데이터베이스 접근 및 조작을 방지하기 위함 |
점검 대상 | 웹 애플리케이션 소스코드, 웹 방화벽 |
1. 사용자 입력 값에 특수문자나 임의의 SQL 쿼리를 삽입하여 DB 에러 페이지가 반환되는지 확인

임이의 SQL 쿼리를 전달하여 DB 에러페이지가 반환되는지 확인했다.

에러 페이지 대신 alert가 반환되었다.
2. 사용자 입력 값에 임의의 SQL 참, 거짓 쿼리를 삽입하여 참, 거짓 쿼리에 따라 반환되는 페이지가 다른지 확인

게시판 검색 창에 ’ or 1=1# SQL 쿼리를 삽입했다.
이는 언제나 참이므로 작동이 된다면 모든 게시글이 보여야 한다.

게시글이 보이지 않았고, =이 필터링이 된 것인지 보이지 않는 것을 확인할 수 있었다.
3. 로그인 페이지에 참이 되는 SQL 쿼리를 전달하여 로그인되는지 확인

로그인 페이지에 ’ or 1=1# SQL 쿼리를 삽입했다.
이 또한 작동된다면 로그인이 되어야 한다.

로그인이 되지 않았다. 따라서 홈페이지에 SQL 취약점은 존재하지 않는다.
보안 설정 방법
- SQL 쿼리에 사용되는 문자열의 유효성을 검증하는 로직 구현
- 특수문자를 사용자 입력 값으로 지정 금지 (아래 문자들은 해당 데이터베이스에 따라 달라질 수 있음)
- Dynamic SQL 구문 사용을 지양하며 파라미터에 문자열 검사 필수적용
- 시스템에서 제공하는 에러 메시지 및 DBMS에서 제공하는 에러 코드가 노출되지 않도록 예외처리
- 웹 방화벽에 인젝션 공격 관련
특수문자 예시
문자 | 설명 |
‘ | 문자 데이터 구분기호 |
; | 쿼리 구분 기호 |
--, # | 해당라인 주석 구분 기호 |
/* */ | * 와 */ 사이 구문 주석 |
문자열 유효성 검증 로직 구현
특정 문자열 필터링을 적용한다.
request로 입력 값을 가져오는 경우 입력 값에서 특수문자를 제거하여 바인딩하는 소스를 삽입한다.
replaceAll() 메소드를 사용하여 구현하였다.
private string SafeSqlLiteral(string inputSQL)
{
Str = inputSQL.Replace("'","''");
Str = str. Replace(";","");
Str = str. Replace("--","");
Str = str. Replace("|","");
Str = str. Replace(":","");
Str = str. Replace("+","");
Str = str. Replace("\","");
Str = str. Replace("/","");
.....
return str;
}
Dynamic SQL
Private void cmdLogin_Click(object sender, System.EventArgs e) {
string strCnx = ConfigurationSettings.AppSettings[“cnxNWindBad”];
Using (SqlConnection cnx = new SqlConnection(strCnx))
{
SqlParameter prm;
Cnx.Open();
string strQry = “SELECT Count(*) FROM Users WHERE UserName = @username “ + “AND Password = @password”;
Int intRecs;
SqlCommand cmd = new SqlCommand(strQry, cnx);
cmd.CommandType = CommandType.Text;
prm = new SqlParameter(“@username”,SqlDbType.VarChar,50);
prm.Direction = ParameterDirection.Input;
prm.Value = txtUser.Text; cmd.Parameters.Add(prm);
prm = new SqlParameter(“@password”,SqlDbType.VarChar,50);
prm.Direction = ParameterDirection.Input;
prm.Value = txtPassword.Text;
cmd.Parameters.Add(prm);
intRecs = (int) cmd.ExecuteScalar();
if(intRecs > 0) {
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false);
}
else {
lblMsg.Text = “Login attempt failed.”;
}
}
}