SQL 인젝션 (SQL Injection) - MSSQL

SQL Injection

설명

SQL 인젝션은 외부 입력값이 SQL 쿼리문에 직접 포함되어 실행될 때 발생하는 취약점입니다. 공격자는 쿼리에 특수 문자를 삽입하여 의도하지 않은 데이터 접근, 데이터 변조, 또는 시스템 명령 실행 등이 가능합니다. 특히 문자열 연결(+)이나 템플릿 리터럴 등으로 사용자 입력을 쿼리에 직접 결합할 경우, 손쉽게 공격이 이루어질 수 있습니다.

잠재적 영향

  • 데이터 유출(데이터 노출): 공격자가 암호 같은 민감한 정보를 확인할 수 있습니다.

  • 데이터 변조(데이터 변경): 데이터베이스의 데이터를 마음대로 추가, 수정, 삭제할 수 있습니다.

  • 서비스 거부(서비스 마비): 악의적인 쿼리로 데이터베이스와 애플리케이션을 다운시킬 수 있습니다.

해결 방법

  • 사용자 입력값을 쿼리에 직접 포함하지 않고, 반드시 파라미터화(Prepared Statement)나 쿼리 바인딩을 사용해야 합니다.

  • 입력값의 타입, 길이, 허용 문자 등을 사전에 명확히 검증합니다.

  • 쿼리를 동적으로 만들 때는 문자열 연결을 절대 사용하지 않습니다.

취약한 코드 및 안전한 코드 예시

취약한 코드

const express = require('express');
const mssql = require('mssql');

app.get('/user', async (req, res) => {
  const id = req.query.id;
  const pool = mssql.connect(/* config */);
  const request = (await pool).request();
  // 위험: 사용자 입력값을 직접 쿼리에 포함
  const result = await request.query(`SELECT * FROM users WHERE id = ${id}`);
  res.json(result);
});

안전한 코드

설명:

  • 취약한 코드: 사용자 입력값(id)을 검증 없이 SQL 쿼리문에 바로 포함시킵니다. 공격자는 id에 악의적인 SQL 내용을 삽입하여 전체 데이터베이스를 조작할 수 있습니다.

  • 안전한 코드: 입력값을 숫자로 검증하고, 파라미터화된 쿼리로만 값을 전달합니다. 이 방법은 입력값에 어떠한 특수 문자가 들어가도 쿼리 구조가 변하지 않으므로 안전합니다.

참조

Last updated