SQL Injection
SQL Injection이란
- 애플리케이션의 보안 허점을 이용해 악의적인 SQL문을 실행시켜 DB를 비정상적으로 조작하는 코드 인젝션 공격 방법.
- SQL문이
데이터
와 SQL을 제어하는 명령어
로 구성된다는 점에 의거.

공격 방법
- 다음과 같이 USER_INPUT 위치에 입력한 이름의 사용자를 찾는 SQL을 공격한다고 가정.
SELECT * FROM users
WHERE name='USER_INPUT' AND age=2;
- USER_INPUT에
' OR '1'='1'; --
를 입력한 다면, 다음과 같이 모든 사용자를을 찾는 SQL이 됨.
SELECT * FROM users
WHERE name='' OR '1'='1'; --'AND age=2;
- USER_INPUT에
a'; DROP TABLE users; --
를 입력한 경우, 다음과 같이 users 테이블을 지워 버림.
SELECT * FROM users
WHERE name='a'; DROP TABLE users; --' AND age=2;
Blind SQL Injection
- 공격자가 SQL 결과를 직접적으로 알 수 없지만, SQL injection에 취약한 웹 사이트 등에 사용하는 공격 방법.
https://ex.com/id=5
와 같은 URL이, 서버에서 다음과 같은 SQL을 동작한다고 가정.
SELECT * FROM users WHERE id=5;
https://ex.com/id=5 OR 1=1
, https://ex.com/id=5 AND 1=2
라는 두 URL로 접속을 시도할 경우, 다음과 같은 SQL들이 생성됨.
SELECT * FROM users WHERE id=5 OR 1=1;
SELECT * FROM users WHERE id=5 AND 1=2;
- 첫 번째 URL은 정상적으로 실행되고, 두 번째 URL은 오류 페이지를 보여주는 경우, SQL injection에 취약하다는 것을 알 수 있음.
- 이후 여러 방식으로 쿼리들을 보내 원하는 정보를 탈취.
방어 방법
- ORM
- Hibernate와 같이 SQL이 string으로 구성되지 않는 안전한 ORM 프레임워크 이용.
- Web application firewall
- DB 단에서의 완벽한 방지는 아니지만 SQL 공격을 한 차례 거를 수 있음.
- Prepared(Parametrized) statements
- 입력받는 위치에 특정한 type의 값만 저장할 수 있는 placeholder 변수를 두는 방법.
- 이후 이 변수를 문자열로 바꿈,
- Escaping
- 사용자가 입력한 값에서 SQL에서 의미를 갖는 모든 특수문자 앞에 \를 붙여 escape 하는 방법.
- PHP등의 언어에서는
mysqli_real_escape_string()
등의 함수로 지원.
- Pattern Check
- 사용자가 입력한 값의 type 혹은 pattern을 체크하는 방법.
- DB Permissions
- 웹 어플리케이션에서 DB에 접속하는 경우 권한을 필요한 것으로만 제한함으로 인해 SQL injection을 일부 방지하는 방법.
References
- https://xkcd.com/327/
- https://en.wikipedia.org/wiki/SQL_injection