728x90
csrf 사이트 간 요청 위조 (Cross-site request forgery)
사이트 간 요청 위조는 웹사이트 취약점 공격의 하나로, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 특정 웹사이트에 요청하게 하는 공격을 말한다. 유명 경매 사이트인 옥션에서 발생한 개인정보 유출 사건에서 사용된 공격 방식 중 하나다.
![](https://blog.kakaocdn.net/dn/vnekN/btsDIyTfMyD/dzMmArKyscpeUA7xGDfK61/img.png)
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 공격을 방지하는 기능을 지원하고 있다.
![](https://blog.kakaocdn.net/dn/8MFlh/btsDQdsY1lx/G5WrdJERED29K08cfM5uR1/img.png)
@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을 사용할 수가 없다.
![](https://blog.kakaocdn.net/dn/bk9NKG/btsDQhvlf6m/mqhFGS3coo3Uy2ahHQR5n0/img.png)
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도 알아보자.
![](https://blog.kakaocdn.net/dn/brxsdH/btsDLtiO7pB/ByMEIvNhnuUUBR6hNnto00/img.gif)
728x90