Side-project : Spring Security + CSRF Token 활용하기(2)

우진·2023년 6월 12일
0
post-thumbnail
post-custom-banner

👾 Spring Security

https://docs.spring.io/spring-security/reference/index.html


👾 Use CSRF Token In Spring Security

CSRF 공격이란?
Cross-Site Request Forgery
사이트 간 요청 위조의 줄임말.
웹 애플리케이션 취약점 중 하나로 사용자가 자신의 의지와 무관하게 공격자가 의도한 행동을 해서 특정 웹페이지를 보안에 취약하게 한다거나 수정, 삭제 등의 작업을 하게 만드는 공격 방법이다.


(1) 👾 Use CSRF Token With CKEditor4

중간에 CKEditor4가 끼게 되면 난이도가 부쩍 오른다.. (º﹃º ) 직접 만든 폼에서 비동기 통신을 할 경우, 요청헤더 설정이 가능하기때문에 토큰을 함께 보내줄 수 있지만 이 경우 아직 해결법을 찾지 못했다. 이슈 사항은 아래와 같다.


< 일반적인 사용법 >
Security로 부터 정해진 HTML 태그에 CSRF 토큰을 전달 받음 ->
JS로 비동기 통신할 때 요청 헤더에 받은 토큰을 넣어 서버로 전달 ->
(토큰이 일치) 요청 수행 / (토큰이 불일치) 403 오류코드 반환

< CKEditor4에서의 사용법? >
Security로 부터 정해진 HTML 태그에 CSRF 토큰을 전달 받음 ->
HTML 하단의 <script>에서 서버의 매핑 URL을 정해주면 알아서 요청 수행 ->
요청 헤더에 토큰을 설정할 수 없음


그래서 차선책으로, CKEditor4 이미지 업로드에 사용되는 URL만 CSRF 토큰 사용을 비활성화해두기로 했다. ..( ;ㅁ; )‬ 따흑


(1 - 1) 📁 Update SecurityConfig

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .cors().and()
                .csrf()
                .ignoringRequestMatchers("/boards/ck/imageUpload.do")
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
                
                ... ;

        return http.build();
    }
  • .ignoringRequestMatchers(): CSRF Token 사용을 부분 비활성화시킬 url을 설정한다.

(2) 👾 Use CSRF Token With Fetch API


이 경우, 직접 비동기 통신을 진행하므로 문제될 게 없다.


(2 - 1) 📁 Update csrfHeaders.js

이전 포스팅에서 fetch API로 요청할 때 헤더에 넣을 내용을 변수로 분리했었다. 여기에 추가해준다.

//csrf token
const csrfHeader = document.querySelector('meta[name="_csrf_header"]').content;
const csrfToken = document.querySelector('meta[name="_csrf"]').content;

//headers 에 csrfToken 설정
//json 타입
...

//multipart 타입
const multipartHeaders = {
};
multipartHeaders[csrfHeader] = csrfToken;

왜 이전처럼 Content-Typemultipart/form-data로 명시하지 않냐면, 그렇게하면 403 오류가 반환되기 때문이다.

Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN' ...

이유는 나도 모른다. security에서 인식이 안된다나 뭐라나. 어떤 분들은 web.xml을 고치던데 안타깝게도 내 프로젝트에는 web.xml이 없다 ㅋㅠㅋ; 그래서 Content-Type을 명시하지 않는 방법을 사용했다. 이렇게 하면 또 작동한다. 마찬가지로 이유는 모르니까 묻지 마시길

< 참고 >
HTML 파일에서 태그는 아래와 같이 사용했다.

	<input id="profile" name="profile" type="file">

보기엔 간단해 보이는데 왜 헤맸냐고?? 그것도.. 묻지마....짲응나니까

profile
백 개발을 시작한 응애개발자
post-custom-banner

0개의 댓글