SQL 인젝션

최근 편집: 2022년 12월 27일 (화) 14:25

SQL 인젝션(SQL Injection)은 해킹 공격 기법 중 하나로, 데이터베이스 이용을 위해 SQL를 사용하는 응용프로그램의 취약점을 이용해 실행 SQL 문장을 변조하여 의도와 다른 일을 수행하도록 하는 공격 기법이다.

원리

로그인을 수행할 때 응용프로그램에서는 데이터베이스에 SELECT 쿼리를 보내 해당하는 ID와 비밀번호와 일치하는 레코드를 가져와 한 개 이상의 레코드를 가져오는데 성공하면 로그인에 성공했다고 인식하게 되는데, SQL 인젝션이 가능한 보안 취약점이 있는 경우 ID만 알고 있으면 비밀번호를 몰라도 일치하는 레코드를 가져오게 하는 것이 가능하다. ID를 입력할 때 ID와 함께 ' OR 1=1 --과 같은 문장만 입력하면 되는 것. 이렇게 하면 -- 문법 뒤의 모든 내용이 주석이 되기 때문에 해당 ID에 해당하는 모든 레코드를 가져오게 되기 때문.

예를 들어 SELECT * FROM EXAMPLE_MEMBERS WHERE MEM_ID='id' AND MEM_PW='pw'; 문장은 SQL 인젝션을 통해 SELECT * FROM EXAMPLE_MEMBERS WHERE MEM_ID='id' OR 1=1 --' AND MEM_PW='pw';으로 변조되어 실행된다.

이 방법으로 관리자 계정으로 로그인하거나, 또는 심한 경우 데이터베이스 자체를 날려버리는 공격도 가능하다.

방어 방법

SQL에 프로그래밍 방식으로 집어넣게 되는 값들에서 특수문자를 날려버리거나 따로 텍스트 인코딩을 수행하면 해결된다.

예를 들어 로그인 폼에 femiwiki' --와 같은 값이 들어오면 특수문자를 모두 날려 femiwiki로 만들거나, Base64 인코딩을 수행하여 ZmVtaXdpa2knIC0t로 바꾸면 된다. 다만 Base64 인코딩은 검색 방법, 속도 등에 있어서 불편한 점이 많기 때문에 보통은 특수문자를 날려버리는 방식으로 해결한다.

PHP용 MySQL 라이브러리에서는 SQL 인젝션의 방어를 위한 mysql_real_escape_string 함수를 제공한다. 이 함수는 어떤 값이 SQL 변조가 가능한지 확인하여 해당 문자를 모두 날려버리는 기능을 수행한다. 물론 MySQL 외에도 여러 데이터베이스 라이브러리에서 관련 함수를 제공하고 있다.

미디어위키의 경우 SQL 생성 인터페이스를 제공하고 있어, 예를 들어 한 쿼리를 다음 두 가지 방법으로 처리할 수 있는데 아래쪽이 SQL 인젝션을 막기 위해 권장되는 사용법이다.[1][2]

$dbr = wfGetDB( DB_REPLICA );
$res = $dbr->query('SELECT cat_title, cat_pages FROM category WHERE cat_pages > 0 ORDER BY cat_title ASC')
$dbr = wfGetDB( DB_REPLICA );
$dbr->select(
	'category',
	[ 'cat_title', 'cat_pages' ],
	'cat_pages > 0',
	__METHOD__,
	[ 'ORDER BY' => 'cat_title ASC' ]
);

동향

SQL 인젝션이 가장 기본적인 웹 해킹 기법이기 때문에 어지간한 CMS, 웹 응용프로그램 등은 모두 SQL 인젝션에 대한 대응이 되어 있다. 그러나 일부 웹 사이트에서는 먹히는 경우가 종종 있기 때문에 해커들은 한 번씩은 SQL 인젝션 공격을 해보는 편.

같이 보기

출처

  1. “SQL injection”. 《미디어위키》. 2018년 10월 30일에 확인함. 
  2. “Wikimedia\Rdbms\Database Class Reference”. In new code, the query wrappers select(), insert(), update(), delete(), etc. should be used where possible, since they give much better DBMS independence and automatically quote or validate user input in a variety of contexts.