일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 오버라이딩
- 스프링 CRUD게시판
- crud게시판
- 스프링게시판만들기
- html기초
- 정보처리기사실기정리
- 2020정보처리기사실기정리
- spring crud게시판
- jsp 팝업띄우기
- CRUD게시판만들기
- 자바 정규표현식 예제
- 자바연산자
- 프로그래머스 SQL
- 자바기초
- 프로그래머스 MYSQL
- PLSQL
- spring crud
- 2020정보처리기사실기요약
- 날짜지정팝업
- 정처기실기정리
- Oracle기초
- 자바배열예제
- 게시판만들기
- js datepicker
- 2020정보처리기사실기
- jsp게시판만들기
- jsp 날짜팝업
- 스프링 crud
- 오라클설치
- 프로그래머스 쿼리문
- Today
- Total
영보의 SystemOut.log
SQL Injection 취약점과 대응 방법 본문
취약점 설명 및 사례
1.1) 취약점 설명
데이터베이스(DataBase)와 연동된 웹 어플리케이션에서 공격자가 입력 폼 및 URL 입력란에 SQL문을 삽입하여 DB로부터 정보를 열람(또는 조작)할 수 있는 취약점
1.2) 사례
- ㅇㅇ포털 사이트의 URL에 거짓 코드(Query)를 삽입하면 비정상적인 화면이 노출
- DB 이름의 길이를 알아내는 SQL 코드를 삽입하면 DB이름을 찾아내고, 매개변수 값에 오류를 발생시키는 코드('+\\+"+\\+')를 삽입하여 페이지를 요청하면 카테고리 값이 변경되어 출력됨
점검 방법
2.1) 로그인 페이지 점검
가) 관리하고 있는 웹서버의 로그인 페이지로 이동
나) 아이디와 패스워드 란에 아래 문자열을 입력하여 결과 확인
// 점검 예)
아이디 : ' or 1=;--
비밀번호 : ' or 1=1;--
다) 인증 실패 메시지가 나타날 경우 => SQL Injection취약점은 존재하지 않음
라) 로그인이 될 경우 SQL Inejction 취약점이 존재
마) 웹서버 오류 메시지가 나타날 경우, SQL Injection 가능성이 있으므로 정보시스템, 홈페이지 보안가이드을 참고하여 세부적인 점검이 필요함
필터링 대상 | |||
'or 1=1;- - | or 1=1-- | ')or('a'='a | + or 1=1- - |
' ' or 1=1- - | 'or 'a'='a | sql' or 1=1- - | " |
"or 1=1 -- | " or "a"="a | sql" or 1=1-- | ' |
2.2) 페이지 입력값 점검
가) 관리하고 있는 웹서버의 게시판으로 이동
나) 게시판 등의 게시물 링크를 복사하여 브라우저의 주소표시줄에 입력
다) 주소표시줄에 입력한 값 중 게시판 번호(또는 글 번호) 등의 입력 값에 아래 예와 같이 인용부호( ' 또는 " )를 입력하여 결과 확인
// 점검 예)
http://www.점검사이트.es.kr/bbs/view.asp?Name=Notice&bbs=09"
http://www.점검사이트.es.kr/bbs/view.asp?bbs=01"&page=09
라) 내용에 DB오류 또는 웹서버의 디렉터리가 노출될 경우, 입력값 검증 부재로 인해 추가 SQL Injection 공격을 차단(특수문자 치환 등)하는 장치가 마련되어 있지 않아 취약한 것을 의미
대응 방안
3.1) 웹 서버 내에서의 조치
가) 웹 서버의 오류 정보가 사용자에게 노출되지 않도록 조치
나) 웹 애플리케이션과 연동되는 데이터베이스의 접근 권한을 최소화
다) 사용자 입력 폼(로그인 폼, 검색 폼, URL 등)을 대상으로 특수문자, 특수구분 필터링 규칙 적용
필터링 대상 | |||||
' | " | -- | # | ( | ) |
= | */ | /* | + | < | > |
user_tables | user_table_columns | table_name | column_name | syscolumns | |
union | select | insert | drop | update | and |
or | if | join | substring | from | where |
declare | substr | openrowset | xp_ | 'sysobjects | % |
3.2) 홈페이지 개발 보안 조치
가) 홈페이지 소스코드는 사용자로부터 입력되는『입력 값』에 대한 검증과 예외처리
① ID, PASSWORD, 게시판 제목, 본문, 검색창, 주소검색창 등의 모든 입력란에 특수문자 (등호, 부등호, 인용부호 등)를 직접 입력하지 못하도록 웹서버의 소스코드를 수정
② 입력 값에 정의된 문자 길이를 검증하여 SQL문이 추가 삽입되지 않도록 예외처리
③ 파라미터가 숫자인 경우 isnumeric과 같은 함수를 이용하여 검증하며, 문자인 경우 정규표현식을 이용하여 특수문자를 치환 특히 sql문에서 활용되는 문자(', ", ;, --, or 등)는 반드시 치환
3.3) 보안 코드 사용
대부분의 SQL 주입 인스턴스는 쿼리 내에서 문자열 연결 대신 매개변수화된 쿼리(prepared 문)를 사용하여 방지할 수 있다.
※ 다음 코드는 사용자 입력이 쿼리에 직접 연결되기 때문에 SQL 주입에 취약합니다.
String query = "SELECT * FROM products WHERE category = '"+ input + "'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
String sql= "SELECT*FROM user_table" + "WHERE id = ?" + "AND password =?";
ResultSet rs = null;
PreparedStatement pstmt = null;
try
conn = DBManager.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, request.getParameter("id"));
pstmt.setString(2, request.getParameter("password"));
rs = pstmt.executeQuery();
※ 이 코드는 사용자 입력이 쿼리 구조를 방해하는 것을 방지하는 방식으로 쉽게 다시 작성할 수 있다.
PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");
statement.setString(1, input);
ResultSet resultSet = statement.executeQuery();
매개변수화된 쿼리 WHERE는 INSERTor UPDATE문의 절과 값을 포함하여 신뢰할 수 없는 입력이 쿼리 내 데이터로 나타나는 모든 상황에 사용할 수 있다 . 테이블이나 열 이름 또는 ORDER BY절 과 같은 쿼리의 다른 부분에서 신뢰할 수 없는 입력을 처리하는 데 사용할 수 없다 . 신뢰할 수 없는 데이터를 쿼리의 해당 부분에 배치하는 응용 프로그램 기능은 허용된 입력 값을 화이트리스트에 추가하거나 다른 논리를 사용하여 필요한 동작을 제공하는 것과 같은 다른 접근 방식을 취해야 한다.