[ Node ] Mysql 라이브러리에서 Sql Injection 예방을 위한 파라미터 바인딩

2024. 7. 17. 15:14프로그래밍/Node

개요

사내 데이터베이스는 MySQL을 사용하고 있고 Node를 사용하고 있기 때문에 node-mysql 라이브러리를 사용하고 있다.

그러던 중 문득 우리 서버는 SQL Injection으로부터 안전한지 궁금해져 글을 쓰게 됐다.

 

 

SQL Injection이란?

SQL injection은 말 그대로 쿼리문에 sql 명령어를 삽입하면 명령어가 그대로 실행되는 취약점을 노린 보안 공격이다.

예를 들어 다음과 같은 것이 가능하다. 

const name = req.body.name;
const sql = "select * from user where name=" + name
db.query(sql, function(response,err){
	...
})

 

 

이 때 클라이언트에서 다음과 같이 요청(request) 페이로드를 전달하게 되면 쿼리문이 그대로 실행되게 된다.

{
	"name" : "1; drop table user;"
}

 

const name = req.body.name; # "1; drop table user;"
const sql = "select * from user where name=" + name 
# "select * from user where name=1; drop table user;"
db.query(sql, function(response,err){
	...
})

위와 같이 하나의 sql문으로 실행된다. 따라서 이러한 취약점을 방지하기 위해서 DB 드라이버 역할을 하는 라이브러리들은 파라미터 바인딩(parameter binding) 기능을 제공한다. 

 

mysql 라이브러리 기준으로 위 쿼리는 다음과 같이 사용할 수 있다.

const name = req.body.name;
const sql = "select * from user where name=?"
db.query(sql,[name], function(response,err){
	...
})

? 문자를 사용해서 파라미터 바인딩을 시켜준다. 물론 이는 라이브러리 별로 상이하다(typeORM의 경우 콜론(:))

위와 같이 query 메서드를 호출할 경우 어떻게 동작하길래 안전하게 동작하는 것일까? 알고보면 간단할 것이다.

 

Prepared Statement이란?

위와 같이 특수 문자를 사용해서 sql문의 value로 주어진 변수를 치환할 경우 이는 안전하게 sql문으로 변환된다.

이를 알기 위해서는 공식문서 및 github 공식 Repository를 참고하면 알 수 있다.

이렇게 쿼리의 안정성을 보장하기 위해 파라미터 바인딩을 통해 쿼리문을 실행하기 전 구문 준비 단계를 Prepared Statement라고 한다.

이는 SQL에서 실제로도 명령어로 사용할 수 있는 기능이기도 하다.

 

버전은 다르지만 node-mysql2 라이브러리 개발자의 말에 의하면 query메서드의 파라미터 바인딩은 클라이언트 단계(백엔드 서버)에서 수행되는 것이며 서버(mysql 서버)에서 Prepared Statement를 실행하지는 않는다고 한다. 

여담으로 mysql2는 execute메서드가 추가돼 내부적으로 서버단에서의 prepare와 query메서드가 합쳐져 클라이언트 + 서버가 이중으로 prepared statement를 수행해준다고 해서 안정성이 더 높을 것으로 예상 된다.(prepare 메서드는 캐싱된 쿼리를 호출하기 때문에 효율도 더 좋다고 한다)

또한 Prepared Statement는 내부적으로 sqlstring 라이브러리를 사용하여 구현돼있다. 

mysql 라이브러리를 확인해보면 파라미터로 넘어온 value값들을 안전하게 파싱해주거나 정규식을 이용하여 쓸데없는 문자를 제거해준다던가 하는 역할을 수행한다. (sqlstring 링크 참고)

 

 

결론

기능 구현에 급급하기 보다는 내부적으로 기능이 어디까지 구현돼있는지를 알고 선택적으로 라이브러리를 선택할 수 있어야 하고 사용하면서도 정확히 알고 써야 한다는 것을 상기시키게 되었다.

'프로그래밍 > Node' 카테고리의 다른 글

[Typescript] CryptoJS 사용기  (0) 2024.12.01