SQL Injection이란?
SQL 인젝션(SQL 삽입 공격)은 악의적인 사용자가 데이터베이스와 연동된 웹 애플리케이션에서 조작된 질의(쿼리)문을 주입하여 웹 서비스에 대한 DB정보를 열람또는 조작할 수 있는 하나의 취약점입니다. 인젝션 공격은 OWASP Top10 중 첫 번째에 속해 있었으며, 공격이 비교적 쉬운 편이고 공격에 성공할 경우 큰 피해를 입힐 수 있는 공격입니다.
OWASP : 웹에 관한 정보노출, 악성 파일 및 스크립트, 보안 취약점 등을 연구하는 회사.
보안에 큰 영향을 줄 수 있는 보안 취약점목록을 발표합니다
OWASP에서 발표한 10가지의 웹 보안위협
대표적인 사례들
공격방식
이때 로그인이 성공하게 된다면 SQL Injection이라고 할 수 있다
그렇다면 이러한 방식이 왜 실행될 수 있었을까?
- 실제 실행되는 SQL 질의문 ( 사용자의 입력값을 그대로 전달받아 실행)
SELECT * FROM Users WHERE id = 'TESTID@gmail.com' AND password='123' OR "1"="1" //혹은 SELECT * FROM Users WHERE id = '' OR 1=1'--AND password='123'
123 OR 1=1
로 전달한 비밀번호가 SQL 조건에 그대로 들어가면서 1=1
이라는 참조건과 OR(한쪽이라도 true면 전체 조건문이 true) 를 통해 password 부분이 무조건
TRUE
를 반환하게 되고 이때 아이디만 일치하거나 아이디 자체에 집어넣게 된다면 사용자 정보 혹은 관리자 계정(모든 데이터의 최상단에 있는 계정으로 로그인)을 알 수 있게 됩니다- 실제 서버쪽에서 처리하는 SQL 쿼리문 (예시)
const sql = "select * from Users where id='" + QueryString.id + "' AND password ='" + QueryString.password + "'"; con.query(sql, function (err, result) { if (err) throw err; res.send(result); });
이러한 방식을 논리적 오류를 이용하였다해서 오류 기반 SQL 주입(Error based SQL Injection)이라고 합니다
이 외에도
- UNION 기반 SQL 주입(UNION-Based SQL Injection) → UNION 명령을 이용
- 부울(참,거짓) 기반 SQL 주입([Blind] Boolean-Based SQL Injection) → 참과 거짓의 응답을 이용(로그인 , 아이디 중복확인)
- 시간 기반 SQL 주입 → 마찬가지로 참과 거짓의 응답을 이용하는 기법 SLEEP, BENCHMARK
- 저장된 프로시져 SQL 주입 → 저장 프로시저를 이용
- 다량 SQL 주입
대응 방식
위 예시를 바탕으로..
//in Node.js const sql = "select * from Users where id='" + req.params.id + "' AND password ='" + req.params.password + "'"; con.query(sql, function (err, result) { if (err) throw err; res.send(result); });
이러한 방식을 사용하면 안된다 ( 파라미터를 직접 코딩 )
- Parameter Binding (필수적으로 사용됨)
(프로그램에 사용된 구성 요소의 실제 값 또는 프로퍼티를 결정짓는 행위를 의미)
bind variable(PreparedStatement in JAVA) →
“'123' OR "1"="1"”
문장을 돌면서 바꿔준다+효율성let id = req.params.id; //QueryString.id let password = req.params.password; //QueryString.password const sql = 'SELECT * FROM User WHERE id = ? AND password = ?'; dbconn.query(sql, [id , password], function(err, results, field){ ... }); //자동으로 파싱해준다
- 자동으로 SQL의 ‘?’의 순서와 배열 순서가 일치하도록 매핑되어 SQL이 실행됨
- SQL 질의문에 대해서 한번만 실행시키고 이후 값만 바꿔 계속 실행될 수 있음
- 서버에서 발생한 에러메시지를 클라이언트에서 노출시키지 않을 것 ( 정보 노출 )
- 어떤 dbms를 쓰는지, 버전이 무엇인지 등 이러한 부분이 노출되어 악의적으로 사용될 수 있다
- 입력 값에 대한 검증
- 하나의 대응 방식이 될 수 있다