SQL Injection (2) - Like문에서의 Injection

[제목] SQL Injection (2) - Like문에서의 Injection

이전 아티클 해커들의 백도어 SQL Injection에 이어 이번 아티클에서는 SQL의 LIKE문에서 흔히 발생하는 SQL Injection 문제를 다루어 본다. 기본적으로 이전 아티클과 동일한 원칙을 적용한다고 볼 수 있지만, 한편으로는 약간의 특별한 문법을 갖고 있기 때문에 여기서 별도의 예제를 들어 본다.

SQL문에서 자주 사용되는 LIKE문은 특정 부분 문자열이 들어가는 모든 레코드들을 찾아낼 때 사용된다. 예를 들어, 주소중에 Seattle 이 들어가는 모든 레코드들 찾아내기 위해 다음과 같은 쿼리를 쓸 수 있다.

SELECT * FROM Member WHERE Addr LIKE '%Seattle%'
C#에서 이런 특정 부분문자열을 처리하기 위해 다음과 같이 코딩할 수 있다.
public DataSet FilterAddr(string addr)
{
    DataSet ds = new DataSet();
    SqlConnection conn = new SqlConnection(connStr);
    conn.Open();

    string sql = "SELECT name,addr FROM Member WHERE Addr LIKE '%" + addr + "%'";
            
    SqlDataAdapter adapter = new SqlDataAdapter(sql, conn);
    adapter.Fill(ds);
    conn.Close();
    return ds;
}

이 메서드는 주소문자열을 입력받아 해당 문자열이 주소컬럼안에 들어 있는 데이타를 모두 가져오게 된다. LIKE문은 %를 앞이나 뒤 혹은 양쪽 모두에 둘러싸기 때문에 위 C# 코드에서 입력변수 addr 을 %로 감싸고 있다. 하지만, 이렇게 Dynamic SQL 코딩을 하게 되면 SQL Injection으로 해킹을 당하게 된다. 즉, 만약 이 메서드 사용자가 다음과 같이 메서드를 호출한다면, 원하지 않게 임의의 데이타를 해당 테이블에 추가하게 된다.

DataSet ds = obj.FilterAddr("Seattle' INSERT Member(name) VALUES ('Alex') --");

그렇다면, LIKE문에서 SQL Injection을 막기 위해 어떻게 해야하는가? 이전에 설명했듯이 Parameterized Query를 사용하여 해결하게 된다. 그런데, LIKE문은 % 사인을 붙여야 하는데 이를 어떻게 파라미터에 추가해야 하는가? 이는 아래에서 보이듯이 파라미터값 전후로 %를 추가하여 값 자체가 %를 포함하도록 만들어 해결한다.

public DataSet FilterAddr(string addr)
{
    DataSet ds = new DataSet();
    SqlConnection conn = new SqlConnection(connStr);
    conn.Open();
            
    // LIKE 파라미터의 사용
    string sql = "SELECT name,addr FROM Member WHERE Addr LIKE @addr";            
    SqlCommand cmd = new SqlCommand(sql, conn);

    // 파라미터값 앞뒤로 %를 추가
    SqlParameter p = new SqlParameter("@addr", string.Format("%{0}%", addr));
    cmd.Parameters.Add(p);

    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
    adapter.Fill(ds);
    conn.Close();
    return ds;
}

변수 sql 문자열을 살펴보면, LIKE 문에 어떠한 % 사인도 들어 가지 않음을 알 수 있다. LIKE 다음에는 파라미터명인 @addr만을 기입하고, SqlParameter 변수 p를 생성하고 파라미터 값을 지정할 때 파라미터값 앞뒤로 %를 붙이게 된다.



본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.