맡고있던 프로젝트를 OWASP ZAP을 사용하여 웹 취약점 분석을 진행 하였다
https://ko.wikipedia.org/wiki/OWASP_ZAP
OWASP ZAP은 가장 유명한 무료 보안 툴 중 하나라고 한다.
이 툴을 사용해 보안 테스트를 실시하여 웹 어플리케이션의 보안 취약점을 파악할 수 있다.
(이번에 처음 써봤음..ㅎㅎ)
툴을 사용하여 스캐너를 돌려본 결과
X-Content-Type-Options Header Missing
Missing Anti-clickjacking Header
X-Frame-options Http header
Absence of Anti-CSRF Tokens
Buffer overflow 등의 취약점을 알게 되었다.
Spring Security 설정을 하여
response header 안에 저런 부분들을 다 추가해주어야 한다.
(Buffer overflow 해결은 따로 포스팅 예정..)
Spring-Security는 기본적인 보안 값을 제공하기 위해 보안 관련 HTTP 응답 헤더의 기본집합을 제공한다.
header에 다음 항목을 포함한다 !
Cache-Control
X-Content-Type-Options : nosniff
X-Frame-Options : DENY
X-XSS-Protection: 1; mode=block 등
(이 항목들 외에도 몇가지가 더 있음.. )
* Spring Security 설정
개발환경
표준프레임워크 3.9v
spring-security 4.2.11 v
(스프링 시큐리티는 스프링 버전에 의존도를 가지기 때문에 버전을 꼭 확인 해야한다.)
Error :
org.springframework.beans.factory.BeanCreationException
bean with name ‘DAO’
bean with name ‘sqlMapper’
-> 스프링 시큐리티 4.1.3을 처음에 사용했더니 서버 시작했을 때 bean 생성 오류가 계속 발생했었다.
=> 버전을 4.2.11로 변경하고 해결함.
1. pom.xml의 properties에 spring-security를 추가한다.
<pom.xml>
<spring.security.version>4.2.11.RELEASE</spring.security.version>
2. pom.xml에 dependency를 추가한다.
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
</dependency>
dependency를 추가하고 프로젝트 우클릭 -> maven -> update project를 실행해준다.
Maven Dependencies에 추가된 jar들을 확인할 수 있다.
3. web.xml 에 Spring Security Filter를 추가한다.
<!-- Spring Security Filter -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
스프링 시큐리티를 적용하기 위한 필터이다.
필터의 이름은 반드시 springSecurityFilterChain 이어야 한다.
그리고 필터가 적용될 url 패턴은 모든 패턴을 의미하는 ' /* ' 를 쓰도록한다!
주소 호출할 때 쓰던 *.do 사용하면 안됨.
그리고 web.xml에서 context를 불러오는 경로를 한번 더 확인한다.
4. context-security.xml 파일을 생성한다.
(스프링 시큐리티 설정파일임)
-> CSRF만 사용할 것이기 때문에 간단하게 필요 부분만 작성한다.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<authentication-manager />
<http pattern="/**" security="none"/>
<http create-session="never" use-expressions="true">
<csrf />
<intercept-url pattern="/**" access="permitAll" />
<headers>
<frame-options policy="SAMEORIGIN"/>
</headers>
<http-basic />
</http>
</beans:beans>
스프링에서 bean설정하는 방법은 다양하다.
(properties 파일 사용, xml 파일 사용, class로 정의 => 나는 xml파일을 사용했다.)
주의할 점은 pom.xml에 적어놓은 security jar 버전과
xml파일에서의 configuration 스키마 링크가 같아야한다.
여기서 에러 발생함.
context-security의 스키마 로케이션에
http://www.springframework.org/schema/security/spring-security-4.2.xsd 이 부분을
http://www.springframework.org/schema/security/spring-security.xsd" 이렇게 바꾸었다..
(에러메세지가 정확하게는 기억이 안나지만 schema를 업데이트 하라는 내용이었음.. )
이렇게 하면 스프링 시큐리티 설정을 하고 바로 서버를 돌려보면
에러가 뜬다 ^0^v
401 Unauthorized : 아예 비로그인 상태에서 권한이 필요한 요청을 했을때 발생하는 에러
403 Forbidden : 로그인은 했으나 권한이 맞지 않는 경우에 발생하는 에러
구글링을 해보니,
Spring security를 사용하는 경우 Ajax의 POST호출 시 403 Forbidden 에러가 발생한다고 한다.
해결방안으로 csrf().disable()로 csrf를 사용하지 않게 설정하는 방법이 많이 나오는데
그럼 보안에 문제가 될 수 있기 때문에 csrf가 설정되어 있는 상태에서 403 에러를 발생하지 않게 하려고 한다.
해결방법은
Ajax 요청 header에 csrf 토큰을 넣어서 POST요청을 하는 것 !
1. index.jsp 파일 (본인이 사용하는 jsp파일... )에 csrf meta tag를 추가한다.
<index.jsp>
<head>
<meta id="_csrf" name="_csrf" content="${_csrf.token}"/>
<meta id="_csrf_header" name="_csrf_header" content="${_csrf.headerName}"/>
</head>
이렇게 <head> 태그 내에 csrf 토큰 정보를 삽입했다.
(이 방식을 사용해도 되고 form 을 전송할때 input 박스에 값을 넣고 hidden으로 숨겨서 전달해도 됨 ! )
2. Ajax 호출할때 헤더에 csrf를 전달한다.
나는 js파일에서 공통으로 사용하는 부분에
<index.js>
$(document).ready(function() {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader("AJAX", true);
xhr.setRequestHeader(header, token);
}
});
이렇게 csrf 를 전달하도록 작성하였다.
그리고 확인해보니 403에러 발생하지 않음 !
요청헤더에
csrf token이 잘 담겨져 있고,
응답헤더에는
기본적인 시큐리티 설정이 되어있다.
끝 !
* 틀린 부분이 있다면 마음껏 지적해주세요..♥