Захист CSRF за допомогою пружинних MVC та чебрецю

1. Вступ

Thymeleaf - це механізм шаблонів Java для обробки та створення HTML, XML, JavaScript, CSS та відкритого тексту. Щоб ознайомитись із тим’ялиною та весною, погляньте на цей матеріал.

У цій статті ми обговоримо, як запобігти атакам міжсайтових запитів (CSRF) у Spring MVC за допомогою програми Thymeleaf. Щоб бути більш конкретним, ми протестуємо CSRF-атаку для методу HTTP POST.

CSRF - це атака, яка змушує кінцевого користувача виконувати небажані дії у веб-програмі, в якій на даний момент проводиться автентифікація.

2. Залежності Мейвена

Спочатку давайте розглянемо конфігурації, необхідні для інтеграції Thymeleaf з Spring. Бібліотека чебрецю-весна потрібна у наших залежностях:

 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.

Повну реалізацію цього підручника можна знайти в проекті GitHub - це проект на основі Eclipse, тому його слід легко імпортувати та запускати як є.