SQL Injection

개념

SQL Injection에 대해 간단히만 알아보고 넘어가도록 하겠습니다. 웹 해킹 기법중 하나로 웹서버가 데이터베이스로 Query를 날릴때 해커가 악의적인 구문을 삽입한후 실행되도록 하는 공격방법입니다.

방지

1
2
3
4
5
const id = <사용자로 부터 입력받은 값>;
const sql = 'SELECT * FROM users WHERE id=' + id;
connection.query(sql, function(err, rows) {
...
});

위와 같이 SQL 쿼리를 단순 조합하는 방법은 안전하지 않습니다. SQL Injection을 방지하기 위해서는 안전하지 않은 문자들을 escape해주어야 합니다.

escape() 함수

1
2
3
4
5
const id = <사용자로 부터 입력받은 값>;
const sql = 'SELECT * FROM users WHERE id=' + connection.escape(id);
connection.query(sql, function(err, rows) {
...
});

SQL Injection을 막기 위해서는 위의 코드처럼 사용자로 부터 입력받은 안전하지 않은 데이터는 connection.escape()를 통해 sql 구문을 생성하여야 합니다.

? 문자

escape함수대신에 ?문자를 사용할 수 있습니다. ?를 사용하면 위의 방법보다 더 간단하게 사용할 수 있습니다. 여기서 ?params 배열은 순서대로 매치 됩니다.

1
2
3
4
5
6
const id = <사용자로 부터 입력받은 값>;
const sql = 'INSERT INTO users(id, password) VALUES(?, ?)';
const params = [id, password];
conn.query(sql, params, function(err, rows) {
...
});

escapeId() 함수

데이터베이스, 테이블, 컬럼이름등과 같은 SQL Identifier을 사용자로 부터입력받는 경우, escape함수가 아닌 escapeId함수로 escape할 수 있습니다.

1
2
3
4
5
const tableName = <사용자로 부터 입력받은 값>;
const sql = 'SELECT * FROM ' + connection.escapeId(tableName);
connection.query(sql, function(err, rows) {
...
});

?? 문자

앞서 언급한 ?문자와 마찬가지로 escapeId() 함수를 대체하여 사용 할 수 있습니다. ??문자도 마찬가지로 params배열과 순서대로 매치 됩니다.

1
2
3
4
5
6
const tableName = <사용자로 부터 입력받은 값>;
const sql = 'SELECT * FROM ??';
const params = [tableName];
connection.query(sql, params, function(err, rows) {
...
});

마무리

사용자로 부터 입력받는 데이터는 신뢰해서는 안되며 바로 SQL Query를 요청하면 안됩니다. 안전하지 않은 데이터는 이 글에서 소개한 방법등으로 안전하게 처리하여 안전하게 사용하여야 합니다.