본문 바로가기
Web hacking/개념 정리 & 심화

4) SQL injection 및 XSS 보안 대책 상세

by m_.9m 2023. 1. 17.

4. 보안 대책

4.1. SQL Injection

취약점 항목 SQL Injection
취약점 개요 공격자가 임의의 SQL 질의 문을 삽입할 수 있는 공격이다. 사용자의 입력을 SQL 질의 문에 그대로 넣어서 사용했기때문에 발생된다. 이것으로 인해 데이터 우회와 변조, 추가, 추출이 가능하다.
보안 조치 방법
-  보안 조치 방법

1. Mybatis의 경우 
${ }를 #{ }로 바꾸어 주어 SQL Injection에 대한 보안 대책을 적용한다.

 
2. JPA의 경우,
Spring Data JPA를 사용하면 제공하는 API(save(), saveAll() 등)을 사용해 내부적으로 이미 Parameter Binding을 적용시킬 수 있다. 다만, JPA를 사용해 직접 짜는 경우엔 취약할 수 있기때문에 주의해야한다.
 
3. 정적 쿼리의 사용
SQL Injection은 Prepare Statement을 통해 예방될 수 있다. SQL 문은 실행될 때 데이터 베이스 관리 시스템을 통해 실행이 되는데, Prepare Statement를 사용하면 4가지 과정 중 Parsing 과정을 생략할 수 있다. 기존 Parsing 과정을 거치지 않고 이미 존재하는 쿼리 실행 계획을 선택적으로 수정해 속도와 성능을 향상시킨다. Prepare Statement 함수를 사용할 시 Parameter Binding을 적용시켜 입력 값을 “?”로 분리시키는 것을 잊지않아야 한다.



다음은 PHP나 JSP에서 Prepare Statement를 사용하는 경우의 구체적인 예시이다.





* Prepare Statement는 쿼리에 대한 준비된 명령문을 미리 준비함으로써 성능을 개선하기 위해 만들어졌다. DB 서버 메모리의 남용을 방지하기 위해 DML언어(SELECT, INSERT, UPDATE DELETE등)로 된 구문으로 Prepare Statement가 적용된다. 따라서 Order by는 쿼리 결과를 정렬하는 기능으로 Prepare Statement가 만들어진 목적과는 거리가 멀기 때문에 Prepare Statement를 적용할 수 없다.

4. Order by의 경우 Hash Map을 통한 화이트 리스트 방식을 적용해 SQL Injection을 예방할 수 있다.
 
5. 위의 기술 중 어느 것도 적용할 수 없을 시 모든 사용자의 입력을 이스케이프한다. 쿼리에 입력하기 전의 사용자 입력을 이스케이프 하는 것으로 DBMS는 해당 입력을 개발자가 작성한 SQL 코드와 혼동하지 않으므로 가능한 SQL 주입 취약점을 피할 수 있다.


 

4.2. XSS(Cross Site Scripting)

취약점 항목 XSS(Cross Site Scripting)
취약점 개요 XSS(Cross-Site Scripting) 이란 웹 애플리케이션에서 일어나는 취약점으로 관리자가 아닌 권한이 없는 사용자가 웹 사이트에 스크립트를 삽입하는 공격 기법이다. 이 취약점은 웹 애플리케이션이 사용자로부터 입력 받은 값을 제대로 검사하지 않고 사용할 경우 나타난다. 이 취약점으로 해커가 사용자의 정보(쿠키, 세션 등)를 탈취하거나, 자동으로 비정상적인 기능을 수행하게 할 수 있다.
보안 조치 방법
보안 조치 방법
1.공통
HTML에는 미리 예약된 몇몇의 문자가 있으며, 이러한 문자를 HTML예약어라고 부른다. 이러한 HTML 예약 어는 웹 브라우저가 그것을 평소와는 다른 의미로 해석하게 되는데 HTML 예약 어를 기존에 사용하던 의미 그대로 사용하기 위해 별도로 만든 문자 셋을 엔티티라고 한다. 이 엔티티를 적용가능한 모든 곳에 적용한다. HTML Entity는 우회가 불가능하기 때문에 XSS를 막는 가장 정석인 방법이다.



부득이하게 해당 기능을 사용할 수 없는 경우 입력 값 필터링을 한다. 적용이 불가능 한 곳에서는 입력 내용 전부 HTML Entity로 치환한 후 White List 기반 필터링으로 허용 태그를 돌려놓는다. 또는 Black List 기반으로 악용될 수 있는 이벤트 핸들러를 필터링 한다. 블랙리스트 방식은 완전한 보안대책이 될 수 없다.

2. PHP의 경우
XSS가 일어날 수 있는 변수에 htmlspecialchars() 함수를 사용한다.
해당 함수가 필터링 하는 특수문자는 다음과 같다.



3. JSP의 경우
JSTL 라이브러리를 사용해 XSS를 방어할 수 있다. JSTL은 JSP에서 사용될 수 있는 커스텀 태그 라이브러리로 아파치 사이트를 통해 다운로드 받고 선언할 수 있다. 변수를 설정하거나 맴버 변수 값을 설정할 떄 <c:set>을 통해 설정한다.
- <c:set var="name" value="mang">

변수를 사용할 시 <c:out> 태그를 사용한다. 해당 태그의 사용으로 XSS를 대응할 수 있다. c:outs는 특수문자를 필터링 하는 기능을 가지고 있어 위의 htmlspecialchars()와 같이 & ' " < > 를 필터링한다.
- <c:out value="${name}" default="foo">
변수를 사용하지 않는 기본 형태는 다음과 같다.
- <c:out var="name" value="foo">

<c:set>을 통해 정의된 변수를 완전히 삭제할 경우에 <c:remove>를 사용한다.
- <c:remove var="name">

4. Spring의 경우
타임리프같은 템플릿을 사용하는 경우 일반"th:text"를 사용하면 기본적으로 크사에 대한 필터링이 적용된다.

따라서 utext가 아닌 text를 통해 데이터를 받아와야한다. 



또한 getParameter를 통해 값을 받아왔을 때 필터링이 적용되지 않고 Model.addAttribute를 통해 값을 받아온 경우 XSS 필터링이 자동으로 적용되는 것을 확인하였다. 이에따른 적절한 대응방안을 사용할 수 있다.



5. lucy-xss-servlet-filter
(lucy-xss-servlet-filter)
Naver사에서 XSS 공격을 방어하기 위한 자바 서블릿 필터 기반의 라이브러리이다.초기에 lucy-xss-filter이 등장했지만 취약성이 발견되어 lucy-xss-servlet-filter가 개발되었다. 특징으로는 모든 xss 공격으로 의심되는 패턴을 치환하여 컨트롤러에 도착했을 때 변경(치환) 된 값을 사용하도록 한다. 

해당 필터의 동작 원리를 이해하기 위해서는https://myungjjju.tistory.com/264- 웹서비스 구조의 Servlet의 개념을 이해해야한다. 서블릿 필터는 HTTP 요청과 최종 자원(서블릿, JSP, 기타 문서)사이에 위치하여 클라이언트의 요청 정보를 알맞게 변경할 수 있으며 최종 자원과 클라이언트로 가는 응답 사이에 위치해 최종 자원의 요청 결과 또한 변경할 수 있다.
아래 그림을 참고해 더 쉽게 이해가 가능하다.


(그림 출처 : https://javacan.tistory.com/entry/58)