SQL 구문이 궁금한 경우 [메뉴얼] 을 참조하여 도움을 받아보세요
SQL 삽입 공격(Injection) 은 구문에 악의로 코드를 넣어 실행하는 해킹 공격을 말합니다.
의도하지 않은 동적 쿼리(Dynamic Query) 를 생성한 다음 DB 정보를 열람하거나 조작할 수 있기에 우리는 유효성 검증을 할 수 있도록 만들어야 합니다. 대표적인 공격방법은 아래와 같습니다.
SELECT user FROM table WHERE id='아이디' AND password='비밀번호';일반적인 유저는 위와같은 방법으로 접근이 가능합니다. 여기서 비밀번호 란에 password에 '비밀번호'; DROP TABLE table--'; 라는 값을 입력하게 되면 아래와 같은 사태가 벌어집니다.
SELECT 유저 FROM 테이블 WHERE id='아이디' AND password에 '비밀번호'; DROP TABLE 테이블--'; 하이픈 두개 ( — ) 다음으로 오는 문장은 주석처리가 되어 원래 작동해야 할 쿼리는 작동하지 않고 테이블을 삭제하게 됩니다.
이 방법 외에도 'OR'1'='1 등의 값이 쿼리에 들어오면 1 = 1 : ture 가 되어 로그인 성공되는 상황을 만들어 인증을 무력화 시키는 문제를 만듭니다.
아무리 사소한 쿼리라도 GET 방식을 사용할 때는 주의할 필요가 있습니다. 강제로 오류를 출력하여 데이터 베이스의 이름과 구조를 알아냅니다.
https://www.light-coding.com/login.php?value=q and password=''위의 코드는 URL 쿼리스트링을 악용한 방법입니다. 에러가 발생함으로서 테이블 이름과 컬럼 명을 알아낼 수 있기 때문에 조심해야 합니다.
위의 방식처럼 데이터베이스의 취약점을 타겟으로 공격하는 방법이 많이 있지만 방어 하는 방법 또한 예방법으로 많이 소개되어 있기 때문에 검증된 보안 방식이 많습니다
*, –, ‘, “, ?, #, (, ), ;, @, =, *, +, union, select, drop, update, from,
where, join, substr, user_tables, user_table_columns,
information_schema, sysobject, table_schema, declare, dual,…블랙리스트는 막아야 하는 방법이 너무 많기에 일반적으로 화이트 리스트를 활용하는 방법이 더욱 안전합니다.
INSERT INTO table VALUES(?, ?, ?)원본 테이블은 접근권한을 높이고 뷰(가상의 테이블 : view) 로만 접근하게 만들면 원본 테이블이 공격받는 노출량을 줄일 수 있습니다.
Statement 는 사용할 때마다 매번마다 4단계를 거치게 되는데, Prepared Statement 를 사용하면 특수문자를 자동으로 없애는 것 뿐만 아니라 처음 한번만 3단계를 거친 다음 캐시에 남겨 사용하게 됩니다. 인젝션을 예방할 수도 있지만 속도 면에서도 좋은 점이 확실히 있습니다.
사용자 입력 값을 그대로 저장하여 사용하면 문제가 생깁니다. 특히 비밀번호, 위치정보는 개인정보 보호법에 의거 반드시 암호화 해야 합니다. 보안을 위해 반드시 SHA-256 이상을 사용하는 것을 권장합니다
자바스크립트는 공격자가 브라우저에서 기능을 임의로 끌 수 있습니다. 그렇기에 서버에서 다시 한번 더 체크해야 합니다.
마이바티스(MyBatis) 는 쿼리 문을 사용할 때 사용자의 입력을 전달할 때는 ${USER_ID} 를 사용하지 않고 #{USER_ID} 로 사용하는 것을 권장합니다. $를 사용하면 텍스트로 읽히지 않습니다.
추가로 CONCAT 을 사용하여 쿼리를 작성하면 더욱 안전하게 사용이 가능합니다.