node-postgres의 SQL 인젝션: 모두가 놓치는 패턴
발행: (2025년 12월 31일 오후 02:50 GMT+9)
3 min read
원문: Dev.to
Source: Dev.to
취약한 예시
// ❌ This looks fine, right?
async function getUser(userId) {
const query = `SELECT * FROM users WHERE id = '${userId}'`;
const result = await pool.query(query);
return result.rows[0];
}
공격 시연
// Attacker input:
const userId = "'; DROP TABLE users; --";
// Generated query:
// SELECT * FROM users WHERE id = ''; DROP TABLE users; --'
위 쿼리를 실행하면 전체 users 테이블이 삭제되어 데이터가 파괴되고, 비즈니스에 큰 영향을 미칠 수 있습니다.
왜 위험한가
- 입력 검증을 우회할 수 있음 – 클라이언트‑사이드 체크나 단순 정규식에만 의존해서는 안 됩니다.
- 내부 API도 노출될 수 있음 – 내부 엔드포인트가 침해된 서비스에 의해 호출될 수 있습니다.
- 템플릿 리터럴은 단순 문자열 연결 – 자동으로 SQL을 이스케이프하지 않습니다.
- ORM을 사용해도 raw query에서는 보호되지 않음 – 파라미터 바인딩을 ORM에 맡길 때만 안전합니다.
안전한 파라미터화 쿼리 (유일하게 신뢰할 수 있는 패턴)
// ✅ Parameterized query
async function getUser(userId) {
const query = 'SELECT * FROM users WHERE id = $1';
const result = await pool.query(query, [userId]);
return result.rows[0];
}
$1 자리표시는 PostgreSQL에게 전달된 값을 데이터로 처리하도록 지시합니다. 악의적인 입력이 파라미터를 벗어나 실행될 수 없습니다.
eslint-plugin-pg 로 Linting
플러그인 설치
npm install --save-dev eslint-plugin-pg
ESLint 설정
// eslint.config.js
import pg from 'eslint-plugin-pg';
export default [pg.configs.recommended];
lint 오류 예시
src/users.ts
4:17 error 🔒 CWE-89 OWASP:A03 CVSS:9.8 | Unsafe query detected
Fix: Use parameterized query: client.query('SELECT * FROM users WHERE id = $1', [userId])
동적 테이블 이름을 안전하게 처리하기
// ❌ Unsafe – user‑controlled table name
const table = userInput;
pool.query(`SELECT * FROM ${table}`);
// ✅ Safe – whitelist allowed tables
const ALLOWED_TABLES = ['users', 'orders', 'products'];
if (!ALLOWED_TABLES.includes(table)) throw new Error('Invalid table');
pool.query(`SELECT * FROM ${table}`);
선택적 필터와 함께 쿼리 빌드하기
취약한 접근법
let query = 'SELECT * FROM users WHERE 1=1';
if (name) query += ` AND name = '${name}'`; // Injection!
await pool.query(query);
파라미터를 사용한 안전한 접근법
const params = [];
let query = 'SELECT * FROM users WHERE 1=1';
if (name) {
params.push(name);
query += ` AND name = $${params.length}`;
}
await pool.query(query, params);
자료
- npm package: eslint-plugin-pg – PostgreSQL 보안, 연결 관리, 쿼리 최적화를 다루는 13개의 규칙.
- Rule documentation:
no-unsafe-query(플러그인 문서에서 자세히 확인).