CSRF-bescherming met Spring MVC en Thymeleaf

1. Inleiding

Thymeleaf is een Java-sjabloonengine voor het verwerken en creëren van HTML, XML, JavaScript, CSS en platte tekst. Bekijk dit artikel voor een inleiding tot Thymeleaf en Spring.

In dit artikel zullen we bespreken hoe om Cross-Site Request Forgery (CSRF) -aanvallen te voorkomen in Spring MVC met Thymeleaf-applicatie. Om specifieker te zijn, zullen we de CSRF-aanval testen op de HTTP POST-methode.

CSRF is een aanval die een eindgebruiker dwingt om ongewenste acties uit te voeren in een webapplicatie waarin momenteel is geverifieerd.

2. Maven afhankelijkheden

Laten we eerst eens kijken welke configuraties nodig zijn om Thymeleaf met Spring te integreren. De thymeleaf-spring bibliotheek is vereist in onze afhankelijkheden:

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

Merk op dat voor een Spring 4-project de thymeleaf-spring4 bibliotheek moet worden gebruikt in plaats van thymeleaf-spring5. De laatste versie van de afhankelijkheden is hier te vinden.

Om Spring Security te kunnen gebruiken, moeten we bovendien de volgende afhankelijkheden toevoegen:

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

De nieuwste versies van twee aan Spring Security gerelateerde bibliotheken zijn hier en hier beschikbaar.

3. Java-configuratie

Naast de Thymeleaf-configuratie die hier wordt behandeld, moeten we configuratie voor Spring Security toevoegen. Om dat te doen, moeten we de klasse maken:

@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity (secureEnabled = true, prePostEnabled = true) public class WebMVCSecurity breidt WebSecurityConfigurerAdapter uit {@Bean @Override public AuthenticationManager authenticationManagerBean () throws Exception ({return superhentication); } @Override protected void configure (AuthenticationManagerBuilder auth) genereert Uitzondering {auth.inMemoryAuthentication () .withUser ("user1"). Wachtwoord ("{noop} user1Pass") .authorities ("ROLE_USER"); } @Override public void configure (WebSecurity web) genereert Uitzondering {web.ignoring (). AntMatchers ("/ resources / **"); } @Override beschermde ongeldige configuratie (HttpSecurity http) genereert Uitzondering {http .authorizeRequests () .anyRequest () .authenticated () .and () .httpBasic (); }}

Voor meer details en een beschrijving van de beveiligingsconfiguratie verwijzen we naar de Security with Spring-serie.

CSRF-bescherming is standaard ingeschakeld met Java-configuratie. Om deze handige functie uit te schakelen, moeten we deze toevoegen configureren (...) methode:

.csrf (). uitschakelen ()

In XML-configuratie moeten we de CSRF-bescherming handmatig specificeren, anders werkt het niet:

Houd er ook rekening mee dat als we een inlogpagina met inlogformulier gebruiken, we altijd het CSRF-token in het inlogformulier als een verborgen parameter handmatig in de code moeten opnemen:

Voor de overige formulieren wordt het CSRF-token automatisch toegevoegd aan formulieren met verborgen invoer:

4. Geeft de configuratie weer

Laten we verder gaan met het hoofdgedeelte van HTML-bestanden met formulieracties en het maken van testprocedures. In de eerste weergave proberen we een nieuwe student aan de lijst toe te voegen:

   Leerling toevoegen 

In deze weergave voegen we een student toe aan de lijst door ID kaart, naam, geslacht en percentage (optioneel, zoals vermeld in de formuliervalidatie). Voordat we dit formulier kunnen uitvoeren, moeten we dit verstrekken gebruiker en wachtwoord, om ons te authenticeren in een webapplicatie.

4.1. Browser CSRF-aanvalstest

Nu gaan we verder met de tweede HTML-weergave. Het doel hiervan is om te proberen een CSRF-aanval uit te voeren:

We weten dat de actie-URL is // localhost: 8080 / spring-thymeleaf / saveStudent. De hacker wil toegang tot deze pagina om een ​​aanval uit te voeren.

Om te testen, opent u het HTML-bestand in een andere browser, zonder in te loggen op de applicatie. Wanneer u het formulier probeert in te dienen, ontvangen we de pagina:

Ons verzoek is afgewezen omdat we een verzoek hebben verzonden zonder een CSRF-token.

Houd er rekening mee dat HTTP-sessie wordt gebruikt om CSRF-token op te slaan. Wanneer het verzoek wordt verzonden, vergelijkt Spring het gegenereerde token met het token dat in de sessie is opgeslagen om te bevestigen dat de gebruiker niet is gehackt.

4.2. JUnit CSRF-aanvalstest

Als u CSRF-aanvallen niet met een browser wilt testen, kunt u dit ook doen via een snelle integratietest; laten we beginnen met de Spring-configuratie voor die test:

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

En ga verder met de eigenlijke tests:

@Test public void addStudentWithoutCSRF () gooit Uitzondering {mockMvc.perform (post ("/ saveStudent"). ContentType (MediaType.APPLICATION_JSON) .param ("id", "1234567"). Param ("name", "Joe") .param ("geslacht", "M") .with (testUser ())). andExpect (status (). isForbidden ()); } @Test public void addStudentWithCSRF () gooit Uitzondering {mockMvc.perform (post ("/ saveStudent"). ContentType (MediaType.APPLICATION_JSON) .param ("id", "1234567"). Param ("name", "Joe" ) .param ("geslacht", "M"). with (testUser ()). with (csrf ())). andExpect (status (). isOk ()); }

De eerste test zal resulteren in een verboden status vanwege het ontbrekende CSRF-token, terwijl de tweede correct zal worden uitgevoerd.

5. Conclusie

In dit artikel hebben we besproken hoe u CSRF-aanvallen kunt voorkomen met Spring Security en Thymeleaf-framework.

De volledige implementatie van deze tutorial is te vinden in het GitHub-project - dit is een op Eclipse gebaseerd project, dus het moet gemakkelijk te importeren en uit te voeren zijn zoals het is.