SQL Injection
SQL Injection
- 클라이언트의 입력값에 SQL 코드를 넣어 디비를 조작하는 공격 기법이다.
- 이해를 위한 간단한 예시를 들어보면,
- 팀원들의 나이를 정리해둔 페이지가 있다고 한다.
- “팀장님은 “ + age + “세 입니다.”
- 여기서 악의적으로 age를 “말 많은 꼰대 머리는 탈모 증”이라고 입력했다.
- 결과가 “팀장님은 말 많은 꼰대 머리는 탈모 증세 입니다.”가 되어버렸다.
- 악의적인 입력으로 남들이 보면 오해하기 쉬운 결과가 나온 것이다.
- 이 예시에서는 작은 해프닝으로 끝나겠지만, SQL에 악의적인 코드를 주입한다면 데이터가 난장판이 될 것이다.
- 예시에서는 숫자 타입에 문자열을 넣었지만, 실제 db에서는 문자열 타입에 대한 공격이라고 생각하면 된다.
예방 방법
- Parameter Binding
- 가장 간단한 방법이다.
- 클라이언트로부터 받는 입력값을 직접 SQL에 넣는 것이 아닌 파라미터 바인딩으로 넣는 것이다.
1
2
3
4
5
String bookTitle = "book'; DELETE FROM Book WHERE id > 0--"
preparedStatement = connection.preparedStatement("SELECT * FROM Book WHERE title = '" + bookTitle + "'");
- 데이터 바인딩 없이 입력값을 바로 sql에 넣은 형태이다.
- bookTitle은 누군가 악의적으로 작성한 코드이다.
- 뒤에 방해가 될 만한 것은 –으로 주석 처리 해버렸다.
- 이 경우 실질적으로 실행되는 쿼리는 두 개이다.
- SELECT * FROM Book WHERE title = ‘book’;
- DELETE FROM Book WHERE id > 0
- 아무 생각 없이 짠 조회 코드가 순식간에 테이블의 모든 데이터를 삭제해버렸다.
1
2
3
4
5
6
7
String bookTitle = "book'; DELETE FROM Book WHERE id > 0--"
preparedStatement = connection.preparedStatement("SELECT * FROM Book WHERE title = ?");
preparedStatement.setString(1, bookTitle);
- 위는 jdbc에서 파라미터 바인딩하는 코드이다.
- bookTitle 역시 위와 같이 조회는 대충 해버리고 테이블의 데이터를 삭제하는게 진짜 목적이다.
- PreparedStatement의 setString()에서 예방한다.
- 멀티 쿼리를 제한한다.
- ;로 끝내고 다른 쿼리를 집어넣는 행위를 막는 방법이다.
- 설정을 바꿔 멀티 쿼리를 허용할 수 있다.
- 악의적인 공격 시도를 위한 문자를 지워버린다.
- 문자열을 나타내는 ‘ 작은 따옴표를 '로 전부 바꿔버려 쿼리 수행을 막는다.
- 멀티 쿼리를 제한한다.
This post is licensed under CC BY 4.0 by the author.