til
bindvar는 어떻게 SQL Injection을 막는가?
주먹불끈
2023. 8. 30. 17:07
개요
bindvar(= binding variable)은 SQL 쿼리에서 사용하는 변수나 placeholder를 말한다. 주로 데이터베이스 쿼리의 파라미터화된 부분에 데이터를 바인딩하는 데 사용하는데 SQL injection 공격을 예방하는 데 중요한 역할을 한다.
SQL Injection 예시
악의적인 사용자가 다음과 같은 input을 넣으려고 했다고 생각해보자.
input := "John'; DROP TABLE users; --" // 악의적인 사용자 입력
query := "SELECT * FROM users WHERE name = '" + input + "'"
이렇게 생성한 쿼리는 다음과 같으며, 데이터베이스에서 2개의 SQL명령을 실행한다.
- 하나는 John 이라는 이름의 사용자를 users 테이블에서 가져오는 간단한 요청이지만
- 두 번째 명령은 users 테이블을 삭제(drop)하라는 끔.찍.한. 명령인 것이다.
- 참고로 --'부분은 맨 뒤쪽의 작은 따옴표를 주석처리하여 무시하게 하는 테크닉이다.
SELECT * FROM users WHERE name = 'John'; DROP TABLE users; --'
bindvar를 사용한다면?
Go언어의 sqlx 라이브러리를 사용한다고 가정하면 다음과 같이 bindvar를 사용할 수 있다. query의 물음표(?)이다.
이렇게 구현을 하면 어떻게 될까? 이때에 SQL 명령은
- John 을 가져오는 명령이 아니라,
- John'; DROP TABLE users; -- 라는 user를 가져오는 명령이 된다. 이렇게 SQL injection을 방지한다.
input := "John'; DROP TABLE users; --"
query := "SELECT * FROM users WHERE name = ?"
rows, err := db.Query(query, input)
참고. 헷갈리지 마세요.
bindvar는 오직 값을 파라미터로 넣는데 사용할 수 있지, 컬럼이나 테이블 이름을 파라미터로 넣을 수는 없다.
따라서 아래와 같은 sqlx 쿼리 명령은 동작하지 않는다. 참조 링크: https://jmoiron.github.io/sqlx/ 의 bindvar 부분
반응형