Защита на CSRF с пружина MVC и мащерка

1. Въведение

Thymeleaf е Java шаблонна машина за обработка и създаване на HTML, XML, JavaScript, CSS и открит текст. За въведение в мащерката и пролетта, погледнете този текст.

В тази статия ще обсъдим как да предотвратите атаки за фалшифициране на заявки между сайтове (CSRF) в Spring MVC с приложението Thymeleaf. За да бъдем по-конкретни, ще тестваме CSRF атака за HTTP POST метод.

CSRF е атака, която принуждава крайния потребител да изпълнява нежелани действия в уеб приложение, в което в момента е удостоверено.

2. Зависимости на Maven

Първо, нека видим конфигурациите, необходими за интегриране на Thymeleaf с Spring. В thymeleaf-пролет е необходима библиотека в нашите зависимости:

 org.thymeleaf thymeleaf 3.0.11.RELEASE   org.thymeleaf thymeleaf-spring5 3.0.11.RELEASE 

Имайте предвид, че за проект Spring 4 библиотеката thymeleaf-spring4 трябва да се използва вместо thymeleaf-spring5 . Най-новата версия на зависимостите може да бъде намерена тук.

Освен това, за да използваме Spring Security, трябва да добавим следните зависимости:

 org.springframework.security spring-security-web 5.2.3.RELEASE   org.springframework.security spring-security-config 5.2.3.RELEASE  

Най-новите версии на две библиотеки, свързани с Spring Security, са достъпни тук и тук.

3. Конфигурация на Java

В допълнение към покритата тук конфигурация на Thymeleaf, трябва да добавим и конфигурация за Spring Security. За да направим това, трябва да създадем класа:

@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) public class WebMVCSecurity extends WebSecurityConfigurerAdapter { @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user1").password("{noop}user1Pass") .authorities("ROLE_USER"); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/resources/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest() .authenticated() .and() .httpBasic(); } }

За повече подробности и описание на конфигурацията на защитата се позоваваме на серията „Защита с пролет“.

Защитата на CSRF е активирана по подразбиране с Java конфигурация. За да деактивираме тази полезна функция, трябва да добавим това в метода configure (...) :

.csrf().disable()

В XML конфигурацията трябва да зададем CSRF защитата ръчно, в противен случай тя няма да работи:

Моля, обърнете внимание също, че ако използваме страницата за вход с формуляр за вход, трябва винаги да включваме CSRF токена във формата за вход като скрит параметър ръчно в кода:

За останалите формуляри CSRF маркерът автоматично ще бъде добавен към формуляри със скрит вход:

4. Конфигурация на изгледите

Нека да пристъпим към основната част на HTML файлове с действия по формуляр и създаване на процедура за тестване. В първия изглед се опитваме да добавим нов студент към списъка:

   Add Student   
    

В този изглед добавяме студент към списъка, като предоставяме идентификатор , име , пол и процент (по желание, както е посочено в проверката на формуляра). Преди да можем да изпълним този формуляр, трябва да предоставим потребител и парола , за да ни удостовери в уеб приложение.

4.1. Тестване на CSRF атака на браузъра

Сега пристъпваме към втория HTML изглед. Целта му е да се опита да извърши CSRF атака:

Знаем, че URL адресът за действие е // localhost: 8080 / spring-thymeleaf / saveStudent . Хакерът иска да осъществи достъп до тази страница, за да извърши атака.

За да тествате, отворете HTML файла в друг браузър, без да влизате в приложението. Когато се опитате да изпратите формуляра, ще получим страницата:

Заявката ни беше отхвърлена, защото изпратихме заявка без CSRF маркер.

Моля, обърнете внимание, че HTTP сесията се използва за съхраняване на CSRF токен. Когато заявката е изпратена, Spring сравнява генерирания маркер с маркера, съхраняван в сесията, за да потвърди, че потребителят не е хакнат.

4.2. JUnit CSRF Тестване на атаки

Ако не искате да тествате CSRF атака с помощта на браузър, можете да го направите и чрез бърз тест за интеграция; нека започнем с Spring конфигурацията за този тест:

@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = { WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class }) public class CsrfEnabledIntegrationTest { // configuration }

И преминете към действителните тестове:

@Test public void addStudentWithoutCSRF() throws Exception { mockMvc.perform(post("/saveStudent").contentType(MediaType.APPLICATION_JSON) .param("id", "1234567").param("name", "Joe").param("gender", "M") .with(testUser())).andExpect(status().isForbidden()); } @Test public void addStudentWithCSRF() throws Exception { mockMvc.perform(post("/saveStudent").contentType(MediaType.APPLICATION_JSON) .param("id", "1234567").param("name", "Joe").param("gender", "M") .with(testUser()).with(csrf())).andExpect(status().isOk()); }

Първият тест ще доведе до забранен статус поради липсващия CSRF токен, докато вторият ще бъде изпълнен правилно.

5. Заключение

В тази статия обсъдихме как да предотвратим CSRF атаки с помощта на Spring Security и Thymeleaf framework.

Пълното изпълнение на този урок може да се намери в проекта GitHub - това е проект, базиран на Eclipse, така че трябва да е лесно да се импортира и да се изпълнява както е.