Java/Spring

Spring Security CSRF 적용

코딩공부 2021. 4. 22. 14:38

CSRF 란?

사이트 간 요청 위조(또는 크로스 사이트 요청 위조, 영어: Cross-site request forgery, CSRF, XSRF)는 웹사이트 취약점 공격의 하나로, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 하는 공격

 

Spring Security CSRF

  • Session 단위로 무작위 토큰(CSRF Token)을 발급
  • 요청 파라미터에 token을 포함시켜 전송하여 정상 요청인지, 공격자로부터 의도된 요청인지 판단하는 기능 있음
  • 타 사이트에서 본인의 사이트로 form 데이터를 사용하여 공격하려고 할 때, 그걸 방지하기 위해 csrf 토큰 값을 사용하는 것

 

 CSRF 보호 기능 활성화

  • Spring Security에서는 @EnableWebSecurity 지정 시, 자동으로 CSRF 보호 기능이 활성화
  • 비활성화가 필요할 경우, config 파일에 추가

 

 

 

head meta태그에 추가

 

사용법

 

1) POST 방식 FORM 처리

 

form POST 처리

 

goPage : function(type, data, url, returnParam, newTeb){

(... 중략)

	switch (type) {

               (... 중략)

                case 'S':
                    // data 값이 string = form name 전달,
                    // objcet 면 input element 생성해서 form에 삽입
                    if (typeof (data) != 'string' || typeof (data) == 'object') {
                        var form = document.createElement('form');
                        form.id = 'form';


                        for (var key in data) {
                            console.log(data);
                            console.log(key);
                            var input = document.createElement('input');
                            input.name = key;
                            input.value = data[key];
                            input.type = 'hidden';
                            form.appendChild(input);
                        }

                        data = form.id;

                        $(document.body).append(form);
                    }

                    $("#" + data).append(inputHistory);
                    $("#" + data).attr('action', url);
                    $("#" + data).attr('method', 'POST');
                    $("#" + data).attr('enctype', 'application/json');

                    $("#" + data).submit();
                    break;

	}

}

 

    @PostMapping("/one1")
    public String oneItemType1() {

        return "apply/oneItemType";
    }

 

결과 : 페이지 출력 성공 !

 

 

2) Ajax POST 통신

 

controller

var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");

$.ajax({
      type: "POST",            // HTTP method type(GET, POST) 형식이다.
      url: "/apply/one1",      // 컨트롤러에서 대기중인 URL 주소이다.
      success: function (res) { // 비동기통신의 성공일경우 success콜백으로 들어옵니다. 'res'는 응답받은 데이터이다.
      location.href=res;
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) { // 비동기 통신이 실패할경우 error 콜백으로 들어옵니다.
    	alert("통신 실패.")
    }
});

 

결과 : 통신 실패

 

 

var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");

$.ajax({
    type: "POST",            // HTTP method type(GET, POST) 형식이다.
    url: "/apply/one1",      // 컨트롤러에서 대기중인 URL 주소이다.
    beforeSend: function (xhr) {
        xhr.setRequestHeader(header, token); // token
    },
    success: function (res) { // 비동기통신의 성공일경우 success콜백으로 들어옵니다. 'res'는 응답받은 데이터이다.
	    location.href=res;
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) { // 비동기 통신이 실패할경우 error 콜백으로 들어옵니다.
        alert("통신 실패.")
    }
});

결과 : 페이지 이동 완료