[ Node ] 입력받은 값을 포함하는 쿼리문 오류 (SQL injection 경고)

방충림·2023년 4월 7일
4

Catch the error

목록 보기
6/7
post-thumbnail

현상

클라이언트에서 받아온 값을 쿼리문의 일부로 사용하는 서버 코드가 있다. 하지만 무엇이 문제인지 값을 제대로 읽지 못한다.
오류 결과와, 코드는 다음과 같다.

router.get("/duplicatedId", (req, res) => {
  const inputId = req.query.inputId;
  const sqlQuery = `SELECT user_id FROM users WHERE user_id = ${inputId};`;
  db.query(sqlQuery, (err, result) => {
    if (err) throw err;
    res.send(result);
    console.log("result", result);
  });
});

원인

문제는 SQL injection에 있었다. 클라이언트에서 넘어온 입력값이 쿼리문의 일부로 사용되기 때문에, 클라이언트에서 의도하지 않은 값을 입력하면 쿼리문이 예기치 않게 변형될 수 있다. 이 때문에 클라이언트에서 문자열 값을 입력하면 SQL 구문에 오류가 발생하면서 서버가 강제종료될 수 있다.

해결방안

이를 방지하기 위해서는 입력값에 대한 검증과 정제가 필요합니다. 예를 들어, 문자열 값을 가지는 inputId에 대해서는 작은따옴표(')를 이용하여 SQL 구문을 끊지 않도록 처리하는 것이 좋다.

따라서 아래와 같이 inputId를 따옴표로 감싸서 SQL Injection을 방지할 수 있다.

router.get("/duplicatedId", (req, res) => {
  const inputId = req.query.inputId;
  const sqlQuery = `SELECT user_id FROM users WHERE user_id = '${inputId}';`;
  db.query(sqlQuery, (err, result) => {
    if (err) throw err;
    res.send(result);
    console.log("result", result);
  });
});

또는 아래 코드와 같이 '${inputId}' 를 " ? " 으로 대체하고, db.query의 두번째 인자에 배열 형태로 넣어준다. [inputId]
배열의 형태이기 때문에, 물음표가 여러개여도 아래 배열에 순차적으로 적어주기만 하면 가능하다.

router.get("/duplicatedId", (req, res) => {
  const inputId = req.query.inputId;
  const sqlQuery = `SELECT user_id FROM users WHERE user_id = ? ;`;
  db.query(sqlQuery,[inputId] (err, result) => {
    if (err) throw err;
    res.send(result);
    console.log("result", result);
  });
});

하지만, 이런 것만으로는 안전하지 않다. 보다 안전한 방법은 SQL injection 대책을 포함한 ORM(Object-Relational Mapping)을 사용하는 것 등이 있다.

profile
최선이 반복되면 최고가 된다.

0개의 댓글