flawopen.com/SQL 인젝션/Javascript
티켓 번호만 입력해야 하는 창구에 데이터베이스를 조작하는 명령어를 입력하여 전체 회원 정보를 빼내는 공격입니다.
사용자 입력값이 쿼리 텍스트에 직접 결합될 때 발생하며, Node.js에서는 템플릿 리터럴로 인한 실수가 가장 빈번합니다.
2015년 영국의 통신사 TalkTalk는 레거시 SQL 인젝션 취약점으로 15만 명의 개인정보가 유출되어 40만 파운드의 벌금을 부과받았습니다.
출처: 영국 정보위원회(ICO) 조사 결과, 2016년.// userId comes straight from request query
async function getUser(pool, userId) {
const query = `SELECT * FROM users
WHERE id = ${userId}`;
const [rows] = await pool.query(query);
return rows[0];
}
// value is passed separately, never inlined
async function getUser(pool, userId) {
const [rows] = await pool.query(
'SELECT * FROM users WHERE id = ?',
[userId]
);
return rows[0];
}
매개변수화 쿼리는 DB 드라이버가 쿼리 구조를 먼저 확정한 후 값을 별도로 바인딩하여 안전합니다.
mysql2는 ?를 사용하고, pg(PostgreSQL)는 $1, $2를 사용합니다.
타입 검사는 컴파일 시점에만 작동하며 런타임의 문자열 결합 공격은 막지 못합니다.
grep -rn "query(\`.*\${" --include="*.js" --include="*.ts" .
npx eslint --rule 'no-template-curly-in-string: error' .
p/javascript ruleset in CI to catch unparameterized database queries automatically.기본 쿼리 빌더는 안전하지만, raw 쿼리 사용 시에는 반드시 바인딩 매개변수를 써야 합니다.