스프링 - scrf

아침7시개발·2022년 5월 3일
0

스프링

목록 보기
1/6

csrf 사이트 간 요청 위조 (Cross-site request forgery)

사이트 간 요청 위조는 웹사이트 취약점 공격의 하나로, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 특정 웹사이트에 요청하게 하는 공격을 말한다. 유명 경매 사이트인 옥션에서 발생한 개인정보 유출 사건에서 사용된 공격 방식 중 하나다.

spring boot에서 spring security를 사용하기 위해서는 gradle이나 maven에서 주입해줘야 한다. maven은 보기가 불편해서 언젠가부터 사용 안하고 있다.
Gradle은 Maven repository, JCenter repository, Ivy directory 등 다양한 저장소를 지원한다.

plugins {
	id 'org.springframework.boot' version '2.6.3'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.security:spring-security-test'
	testImplementation('org.springframework.boot:spring-boot-starter-test')
}

test {
	useJUnitPlatform()
}

SecurityConfig.java를 만들고 WebSecurityConfigurerAdapter를 상속 받아서 사용한다.
스프링 시큐리티의 어노테이션인 @EnableWebSecurity 어노테이션은 기본적으로 CSRF 공격을 방지하는 기능을 지원하고 있다.

 @Override
    protected void configure(HttpSecurity http)  {
        try {

            http
//                    .csrf().disable().headers().frameOptions().disable()
//                .and()
                    .authorizeRequests()
//                    .antMatchers("/myPage/**","/order/pay").hasRole("USER")
//                    .antMatchers("/excel/**").hasRole("ADMIN")
                    .antMatchers("/").permitAll()
                    .and()
                    .formLogin()
                    .loginPage("/member/login")
                    .permitAll()
                .and()
                    .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/member/logout"))
                    .logoutSuccessUrl("/main");
        } catch (Exception e) {
            logger.error("oops!", e);
        }
    }

이런식으로 아래에 재정의 해서 사용하면 된다.
처음에 잘 몰라서 csrf를 disable하고 frameOptions도 disable 했다.

  <form method="post" th:action="@{/member/login_process}">
            <div class="container">
            ...
  </form>

이런식으로 form에 action을 넣어주면 자동으로 _csrf라는 name의 hidden type의 input이 생성 된다.

<form method="post" action="/member/login_process">
  <input type="hidden" name="_csrf" value="a2e0642e-4aea-4045-9ceb-844fa1800c85">
            <div class="container">
     ...
</form>

이 _csrf가 header에 있지 않으면 json을 사용할 수가 없다.

  var token = document.getElementsByName('_csrf')[0];
  console.log(token);
  $.ajax({
    url: 'url',
    type: "POST",
    headers: {
      'X-CSRF-Token': token.value
    },
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    data:JSON.stringify(member),
    success: function (data) {
      ...
    },
    ...
  });

jquery는 이런식으로 사용하면 된다.

다음에는 frameOptions도 알아보자.

출처

짱구하

profile
쉬엄쉬엄하는 개발자

0개의 댓글