simulate csrf attack
This commit is contained in:
parent
8771311100
commit
e8bfbd7881
@ -238,6 +238,11 @@
|
|||||||
<artifactId>spring-test</artifactId>
|
<artifactId>spring-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-test</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
package org.baeldung.spring;
|
||||||
|
|
||||||
|
import org.baeldung.web.error.CustomAccessDeniedHandler;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
|
||||||
|
// @Configuration
|
||||||
|
// @EnableAutoConfiguration
|
||||||
|
// @EnableWebSecurity
|
||||||
|
// @EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CustomAccessDeniedHandler accessDeniedHandler;
|
||||||
|
|
||||||
|
public SecurityWithCsrfConfig() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
// java config
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
auth.inMemoryAuthentication().withUser("user1").password("user1Pass").authorities("ROLE_USER").and().withUser("admin").password("adminPass").authorities("ROLE_ADMIN");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(final WebSecurity web) throws Exception {
|
||||||
|
web.ignoring().antMatchers("/resources/**");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(final HttpSecurity http) throws Exception {
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/admin/*").hasAnyRole("ROLE_ADMIN")
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
.and()
|
||||||
|
.httpBasic()
|
||||||
|
.and()
|
||||||
|
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
|
||||||
|
;
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -31,6 +31,7 @@ public class WebConfig extends WebMvcConfigurerAdapter {
|
|||||||
public void addViewControllers(final ViewControllerRegistry registry) {
|
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||||
super.addViewControllers(registry);
|
super.addViewControllers(registry);
|
||||||
registry.addViewController("/graph.html");
|
registry.addViewController("/graph.html");
|
||||||
|
registry.addViewController("/csrfHome.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package org.baeldung.web.controller;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
|
// to test csrf
|
||||||
|
@Controller
|
||||||
|
public class BankController {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
@RequestMapping(value = "/transfer", method = RequestMethod.GET)
|
||||||
|
@ResponseBody
|
||||||
|
public int transfer(@RequestParam("accountNo") final int accountNo, @RequestParam("amount") final int amount) {
|
||||||
|
logger.info("Transfer to {}", accountNo);
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write - just for test
|
||||||
|
@RequestMapping(value = "/transfer", method = RequestMethod.POST)
|
||||||
|
@ResponseStatus(HttpStatus.OK)
|
||||||
|
public void create(@RequestParam("accountNo") final int accountNo, @RequestParam("amount") final int amount) {
|
||||||
|
logger.info("Transfer to {}", accountNo);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ public class CustomAccessDeniedHandler implements AccessDeniedHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(final HttpServletRequest request, final HttpServletResponse response, final AccessDeniedException ex) throws IOException, ServletException {
|
public void handle(final HttpServletRequest request, final HttpServletResponse response, final AccessDeniedException ex) throws IOException, ServletException {
|
||||||
response.getOutputStream().print("Error Message Goes Here");
|
response.getOutputStream().print("Error Message Goes Here");
|
||||||
|
response.setStatus(403);
|
||||||
// response.sendRedirect("/my-error-page");
|
// response.sendRedirect("/my-error-page");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>CSRF test on Origin</h1>
|
||||||
|
<a href="transfer?accountNo=1234&amount=100">Transfer Money to John</a>
|
||||||
|
|
||||||
|
<form action="transfer" method="POST">
|
||||||
|
<label>Account Number</label> <input name="accountNo" type="number"/>
|
||||||
|
<label>Amount</label> <input name="amount" type="number"/>
|
||||||
|
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
|
||||||
|
<input type="submit">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -3,15 +3,14 @@ package org.baeldung.csrf;
|
|||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import org.baeldung.spring.ClientWebConfig;
|
import org.baeldung.spring.PersistenceConfig;
|
||||||
import org.baeldung.spring.SecurityJavaConfig;
|
import org.baeldung.spring.SecSecurityConfig;
|
||||||
import org.baeldung.spring.SwaggerConfig;
|
|
||||||
import org.baeldung.spring.WebConfig;
|
import org.baeldung.spring.WebConfig;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
|
||||||
@ContextConfiguration(classes = { SecurityJavaConfig.class, ClientWebConfig.class, WebConfig.class, SwaggerConfig.class })
|
@ContextConfiguration(classes = { SecSecurityConfig.class, PersistenceConfig.class, WebConfig.class })
|
||||||
public class CsrfDisabledIntegrationTest extends CsrfAbstractIntegrationTest {
|
public class CsrfDisabledIntegrationTest extends CsrfAbstractIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
@ -4,15 +4,14 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock
|
|||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import org.baeldung.spring.ClientWebConfig;
|
import org.baeldung.spring.PersistenceConfig;
|
||||||
import org.baeldung.spring.SecurityWithCsrfConfig;
|
import org.baeldung.spring.SecurityWithCsrfConfig;
|
||||||
import org.baeldung.spring.SwaggerConfig;
|
|
||||||
import org.baeldung.spring.WebConfig;
|
import org.baeldung.spring.WebConfig;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
|
||||||
@ContextConfiguration(classes = { SecurityWithCsrfConfig.class, ClientWebConfig.class, WebConfig.class, SwaggerConfig.class })
|
@ContextConfiguration(classes = { SecurityWithCsrfConfig.class, PersistenceConfig.class, WebConfig.class })
|
||||||
public class CsrfEnabledIntegrationTest extends CsrfAbstractIntegrationTest {
|
public class CsrfEnabledIntegrationTest extends CsrfAbstractIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
@ -42,7 +42,8 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
|
|||||||
.authenticationEntryPoint(restAuthenticationEntryPoint)
|
.authenticationEntryPoint(restAuthenticationEntryPoint)
|
||||||
.and()
|
.and()
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.antMatchers("/**").authenticated()
|
.antMatchers("/api/csrfAttacker*").permitAll()
|
||||||
|
.antMatchers("/api/**").authenticated()
|
||||||
.and()
|
.and()
|
||||||
.formLogin()
|
.formLogin()
|
||||||
.successHandler(authenticationSuccessHandler)
|
.successHandler(authenticationSuccessHandler)
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
package org.baeldung.spring;
|
|
||||||
|
|
||||||
import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler;
|
|
||||||
import org.baeldung.security.RestAuthenticationEntryPoint;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
|
||||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableWebSecurity
|
|
||||||
@ComponentScan("org.baeldung.security")
|
|
||||||
public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler;
|
|
||||||
|
|
||||||
public SecurityWithCsrfConfig() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
|
||||||
auth.inMemoryAuthentication().withUser("temporary").password("temporary").roles("ADMIN").and().withUser("user").password("userPass").roles("USER");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(final HttpSecurity http) throws Exception {// @formatter:off
|
|
||||||
http
|
|
||||||
.exceptionHandling()
|
|
||||||
.authenticationEntryPoint(restAuthenticationEntryPoint)
|
|
||||||
.and()
|
|
||||||
.authorizeRequests()
|
|
||||||
.antMatchers("/**").authenticated()
|
|
||||||
.and()
|
|
||||||
.formLogin()
|
|
||||||
.successHandler(authenticationSuccessHandler)
|
|
||||||
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
|
|
||||||
.and()
|
|
||||||
.logout();
|
|
||||||
} // @formatter:on
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public MySavedRequestAwareAuthenticationSuccessHandler mySuccessHandler() {
|
|
||||||
return new MySavedRequestAwareAuthenticationSuccessHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public SimpleUrlAuthenticationFailureHandler myFailureHandler() {
|
|
||||||
return new SimpleUrlAuthenticationFailureHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,10 +1,14 @@
|
|||||||
package org.baeldung.spring;
|
package org.baeldung.spring;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.ViewResolver;
|
||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||||
|
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan("org.baeldung.web")
|
@ComponentScan("org.baeldung.web")
|
||||||
@ -16,12 +20,26 @@ public class WebConfig extends WebMvcConfigurerAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
|
||||||
registry.addResourceHandler("swagger-ui.html")
|
registry.addResourceHandler("swagger-ui.html")
|
||||||
.addResourceLocations("classpath:/META-INF/resources/");
|
.addResourceLocations("classpath:/META-INF/resources/");
|
||||||
|
|
||||||
registry.addResourceHandler("/webjars/**")
|
registry.addResourceHandler("/webjars/**")
|
||||||
.addResourceLocations("classpath:/META-INF/resources/webjars/");
|
.addResourceLocations("classpath:/META-INF/resources/webjars/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ViewResolver viewResolver() {
|
||||||
|
final InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
|
||||||
|
viewResolver.setPrefix("/WEB-INF/view/");
|
||||||
|
viewResolver.setSuffix(".jsp");
|
||||||
|
return viewResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||||
|
super.addViewControllers(registry);
|
||||||
|
registry.addViewController("/csrfAttacker.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>CSRF Attacker</h1>
|
||||||
|
<a href="http://localhost:8080/spring-security-rest-full/transfer?accountNo=5678&amount=1000">Show Kittens Pictures</a>
|
||||||
|
|
||||||
|
<img src="http://localhost:8080/spring-security-rest-full/transfer?accountNo=5678&amount=1000"/>
|
||||||
|
|
||||||
|
<form action="http://localhost:8080/spring-security-rest-full/transfer" method="POST">
|
||||||
|
<input name="accountNo" type="hidden" value="5678"/>
|
||||||
|
<input name="amount" type="hidden" value="1000"/>
|
||||||
|
<input type="submit" value="Show Kittens Picture">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user