📁 정보처리기사

[시큐어 코딩 가이드] 보안 약점 - 입력데이터 검증 및 표현

박개봄 2021. 4. 1. 17:38
728x90

입력데이터 검증 및 표현

 - 프로그램 입력값에 대한 검증 누락, 부적절한 검증, 데이터의 잘못된 형식 지정 등으로 인해 발생하는 보안 약점

 - 대표적으로 SQL 삽입(Injection), 크로스 사이트 스트립트(XSS) 등의 공격이 있다.

 

주요 공격

보안 약점

대응 방안

SQL 삽입

 - 사용자의 입력값 등 외부 입력값이, SQL 쿼리에 삽입되어 공격

 - PreparedStatement 객체 등을 이용

 - DB에 컴파일된 쿼리문(상수)을 전달

크로스 사이트

스트립트 (XSS)

 - 검증되지 않은 외부 입력값에 의해, 브라우저에서 악의적인 코드 실행

 - 입/출력값에 스크립트가 삽입되지 못하도록, & < > " ' / ( ) 등에 대해 문자열 치환 함수 사용

경로 조작 및

자원 삽입

 - 외부 입력된 값의 사전 검증이 없거나 잘못 처리될 경우, 제공되는 시스템 자원에 접근 경로 등의 정보로 이용될 때 발생

 - 경로 순회 공격 위험이 있는 문자 ( " / \ .. 를 제거하는 필터 사용

운영체제

명령어 삽입

 - 운영체제 명령어 파라미터 입력값이 적절한 사전 검증을 거치지 않고 사용될 때, 공격자가 운영체제 명령어를 조작 

 - 웹 인터페이스를 통해 내부로 시스템 명령어를 전달하지 않도록 프로그램 구성

 

SQL 삽입 공격

1) 개념

 - 웹 애플리케이션에서 입력 데이터에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 창 및 URL에 SQL문을 삽입하여 DB로부터 정보를 열람/조작할 수 있는 취약점 공격 기법

 

2) 시큐어 코딩 구현

 - 매개변수를 받는 PreparedStatement 객체를 상수 문자열로 생성하고, 파라미터 부분을 setString 등의 메서드로 설정하여, 외부의 입력이 쿼리문의 구조를 바꾸는 것을 방지한다!

 

 cf) PreparedStstement란?

MYSQL, Oracle, SQL Server 등에서 지원하는 쿼리 객체로, 동일하거나 비슷한 데이터베이스문을 높은 효율성으로 반복적으로 실행하기 위해 사용되는 기능.

 

 ex)

String category = request.getParameter("category");
...
String sql = "SELECT *
			FROM board
            WHERE b_caregory=" + category + ""; //외부로부터 입력받은 값을 검증없이 사용할 경우 안전하지 않음
Connection con = db.getConnection();

//외부로부터 입력받은 값이 처리 없이 쿼리로 수행되어 안전하지 않음
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql); 

조치 전

String category = request.getParameter("category");
...
//외부로부터 입력받은 값은 안전하지 않을 수 있어, PreparedStatement 사용을 위해 ? 문자로 바인딩 변수를 사용
String sql = "SELECT *
		FROM board
               	WHERE b_category = ?"; 
                
Connection con = db.getConnection();
Preparedstatement pstmt = con.prepareStatment(sql); //PreparedStatement 사용

//PreparedStatement 객체를 상수 문자열로 생성하고 파라미터 부분을 setString 메서드로 설정하여 안전하다.
pstmt.setString(1, category);
ResultSet rs = pstmt.executeQuery();

조치 후

 

크로스 사이트 스크립트(XSS) 공격

1) 개념

 - 웹 페이지에 악의적인 스크립트를 포함해 사용자 측에서 실행되게 유도할 수 있는 공격기법

 - 검증되지 않은 외부 입력이 동적 웹페이지 생성에 사용될 경우,

   전송된 동적 웹페이지를 열람하는 접속자의 권한으로

   부적절한 스크립트가 수행되어 정보유출 등의 공격을 유발할 수 있다.

 

2) 순서

 ① 공격자가 악성 스크립트 파일을 웹서버에 설치 (악성 스크립트가 서버에 저장됨)

 ② 클라이언트에서 악성 스크립트가 설치되어 있는 웹 브라우저 실행

 ③ 웹 서버의 악성 스크립트가 실행되어 클라이언트(사용자) 감염

 => 감염 후 개인정보 등이 공격자에게 유출된다.

 

2) 시큐어 코딩 구현

 - 외부 입/출력값에 스크립트가 삽입되지 못하도록 & < > " ' / ( ) 등에 대해 문자열 치환 함수 구현

 - XSS의 3가지 공격방법으로, Reflected XSS, Stored XSS, DOM XSS가 있다.

 

ex)

//외부 입력값이 검증 없이 화면에 출력될 경우,
//공격스크립트가 포함된 URL을 생성할 수 있어 안전하지 않음 (Reflected XSS)
<%String keyword = request.GetParameter("keyword"); %>

//게시판의 입력 form을 통해 외부값이 DB에 저장됨
//-> 검증없이 화면에 출력 시 공격스크립트가 실행되어 안정하지 않음 (Stored XSS)
검색결과 : ${m.content}

<script type = "text/javascript">
//서버를 거치지 않는 공격스크립트가 포함된 URL을 생성할 수 있어 안전하지 않음 (DOM기반 XSS)
document.write("keyword:" + <%=keyword%>);
</script>

조치 전

 

//입력값에 대하여 스크립트 공격 가능성이 있는 문자열 치환
<%String keyword = request.getParameter("keyword"); %>
keyword = keyword.replaceAll("&", "&amp;");
keyword = keyword.replaceAll("<", "&lt;");
keyword = keyword.replaceAll(">", "&gt;");
...

//JSP에서 출력값에 JSTL의  <c:out>을 사용하여 처리
//cf) <c:out> : Java의 system.out.println();와 동일한 기능을 JSP에서 제공하는 태그
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uir = "http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
검색결과 : <c:out value = "&{m.content}"/>

//잘 만들어진 외부 라이브러리를 활용 (NAVER XSS Filter, OWASP ESAPI, OWASP Java Encoder)
<script type = "text/javascript">
document.write("keyword:"
<%=Encoeder.encodeForJS(Encoder.encodeForHTML(keyword))%>);
</script>

조치 후

 

 

 

 

출처 : 정보처리기사 실기책

728x90