pg 라이브러리를 사용해서 express에서 PostgreSQL을 사용하기 위해 공식 문서를 읽어보던 중, 매개변수화된 쿼리(Parameterized query) 항목을 보고 흥미가 생겼습니다. 우선 일반적인 쿼리문과는 다른 형태를 하고 있었고, SQL Injection 공격을 방지한다고 되어 있어서 일반적인 쿼리문보다 좋아 보였습니다. 하지만 공식 문서만 보고는 SQL Injection 공격이 무엇인지, 그리고 매개변수화된 쿼리가 어떻게 SQL Injection 공격에 더 안전한지 알 수가 없어서 관련 정보들을 찾아봤습니다.


1. SQL Injection 이란?

  SQL Injection은 가장 흔한 웹 해킹 기법 중 하나로써 웹 페이지 입력을 통해 SQL 문에 악성 코드를 삽입해서 데이터 베이스를 파괴할 수 있는 기법입니다. SQL Injection은 "1=1"이 항상 true 값을 반환한다는 것을 기반으로 합니다.

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

 

  "1=1"이 항상 true이기 때문에, UserId = 105와 상관없이 항상 true가 되어서 테이블의 모든 행을 반환합니다.

 

  직접 SQL 쿼리를 입력해 보면 이해하기 쉬울 것입니다. 만약 테이블에 user 이름과 비밀번호가 포함되어 있다면 해커는 105 OR 1=1을 삽입하여 데이터베이스의 모든 사용자 이름과 비밀번호에 액세스 할 수 있습니다.


2. 매개변수화된 쿼리(Parameterized query)

  매개변수화된 쿼리는 SQL Injection을 방지하는 효과적인 방법 중 하나입니다. 그 이유는 쿼리 구조와 데이터를 분리하기 때문입니다. 매개변수화된 쿼리의 구조는 다음과 같습니다.

const { pool } = require('../db');

const { UserId1, UserId2 } = req.query;

// 매개변수화된 쿼리 (Parameterized query)
const query = '
SELECT * FROM Users 
WHERE UserId = $1 OR UserId = $2
';
const values = [UserId1, UserId2];

const res = await pool.query(query, values);
console.log(res.rows);

 

  위 코드와 같이 UserId 값은 쿼리에서 직접 입력되는 것이 아니라, 별도의 값으로 전달이 됩니다. 따라서, 데이터는 쿼리의 일부로 해석되지 않습니다. 따라서, 일반적인 쿼리문을 쓰는 것보다 매개변수화된 쿼리를 사용하면 데이터베이스의 안전성을 높이고, SQL Injection 공격을 효과적으로 방어할 수 있습니다.


참고문헌

1. Parameterized Query - node-postgres 공식 문서 (링크)

2. SQL Injection - W3 Schools (링크)

+ Recent posts