CSRF-beskyttelse med fjær MVC og Thymeleaf
1. Introduksjon
Thymeleaf er en Java-malmotor for behandling og oppretting av HTML, XML, JavaScript, CSS og ren tekst. For en introduksjon til Thymeleaf og Spring, ta en titt på denne oppskriften.
I denne artikkelen vil vi diskutere hvordan forhindre Cross-Site Request Forgery (CSRF) angrep i vår MVC med Thymeleaf applikasjon. For å være mer spesifikk, vil vi teste CSRF-angrep for HTTP POST-metoden.
CSRF er et angrep som tvinger en sluttbruker til å utføre uønskede handlinger i et webapplikasjon der det for øyeblikket er godkjent.
2. Maven-avhengigheter
La oss først se konfigurasjonene som kreves for å integrere Thymeleaf med Spring. De thymeleaf-våren bibliotek kreves i våre avhengigheter:
org.thymeleaf thymeleaf 3.0.11.RELEASE org.thymeleaf thymeleaf-spring5 3.0.11.RELEASE
Merk at, for et Spring 4-prosjekt, thymeleaf-spring4 biblioteket må brukes i stedet for thymeleaf-spring5. Den siste versjonen av avhengighetene finner du her.
Videre, for å kunne bruke Spring Security, må vi legge til følgende avhengigheter:
org.springframework.security spring-security-web 5.2.3.RELEASE org.springframework.security spring-security-config 5.2.3.RELEASE
De nyeste versjonene av to Spring Security-relaterte biblioteker er tilgjengelige her og her.
3. Java-konfigurasjon
I tillegg til Thymeleaf-konfigurasjonen som dekkes her, må vi legge til konfigurasjon for Spring Security. For å gjøre det, må vi lage klassen:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity (secureEnabled = true, prePostEnabled = true) offentlig klasse WebMVCSecurity utvider WebSecurityConfigurerAdapter {@Bean @Override public AuthenticationManager authenticationManagerBean () kaster Exception {return; } @ Override beskyttet tomromskonfigurasjon (AuthenticationManagerBuilder auth) kaster Unntak {auth.inMemoryAuthentication () .withUser ("user1"). Passord ("{noop} user1Pass"). Autoriteter ("ROLE_USER"); } @ Override public void configure (WebSecurity web) kaster unntak {web.ignoring (). AntMatchers ("/ resources / **"); } @ Override-beskyttet tomkonfigurasjon (HttpSecurity http) kaster Unntak {http .authorizeRequests () .anyRequest () .authenticated () .and () .httpBasic (); }}
For mer informasjon og beskrivelse av sikkerhetskonfigurasjon, henviser vi til serien Security with Spring.
CSRF-beskyttelse er aktivert som standard med Java-konfigurasjon. For å deaktivere denne nyttige funksjonen må vi legge til dette i konfigurer (...) metode:
.csrf () deaktivere ()
I XML-konfigurasjon må vi spesifisere CSRF-beskyttelsen manuelt, ellers vil det ikke fungere:
Vær også oppmerksom på at hvis vi bruker påloggingsside med påloggingsskjema, må vi alltid inkludere CSRF-token i påloggingsskjemaet som en skjult parameter manuelt i koden:
For de gjenværende skjemaene blir CSRF-token automatisk lagt til i skjemaer med skjult inngang:
4. Visningskonfigurasjon
La oss gå videre til hoveddelen av HTML-filer med skjemahandlinger og oppretting av testprosedyrer. I den første visningen prøver vi å legge til en ny student på listen:
Legg til student
I denne visningen legger vi til en student på listen ved å oppgi id, Navn, kjønn og prosentdel (valgfritt, som angitt i skjemavalidering). Før vi kan utføre dette skjemaet, må vi gi det bruker og passord, for å autentisere oss i en webapplikasjon.
4.1. Nettleser CSRF Attack Testing
Nå fortsetter vi til den andre HTML-visningen. Hensikten med det er å prøve å gjøre CSRF-angrep:
Vi vet at handlings-URL er // localhost: 8080 / spring-thymeleaf / saveStudent. Hackeren ønsker å få tilgang til denne siden for å utføre et angrep.
For å teste, åpne HTML-filen i en annen nettleser uten å logge på applikasjonen. Når du prøver å sende inn skjemaet, vil vi motta siden:
Forespørselen vår ble avvist fordi vi sendte en forespørsel uten et CSRF-token.
Vær oppmerksom på at HTTP-økt brukes for å lagre CSRF-token. Når forespørselen sendes, sammenligner Spring generert token med tokenet som er lagret i økten, for å bekrefte at brukeren ikke er hacket.
4.2. JUnit CSRF Attack Testing
Hvis du ikke vil teste CSRF-angrep ved hjelp av en nettleser, kan du også gjøre det via en rask integrasjonstest; la oss starte med vårkonfigurasjonen for den testen:
@RunWith (SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration (classes = {WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class}) offentlig klasse CsrfEnabledIntegrationTest {// konfigurasjon}
Og gå videre til de faktiske testene:
@Test offentlig ugyldig addStudentWithoutCSRF () kaster unntak {mockMvc.perform (post ("/ saveStudent"). ContentType (MediaType.APPLICATION_JSON) .param ("id", "1234567"). Param ("navn", "Joe") .param ("gender", "M") .with (testUser ())). andExpect (status (). isForbidden ()); } @Test offentlig ugyldig addStudentWithCSRF () kaster unntak {mockMvc.perform (post ("/ saveStudent"). ContentType (MediaType.APPLICATION_JSON) .param ("id", "1234567"). Param ("navn", "Joe" ) .param ("kjønn", "M") .med (testbruker ()). med (csrf ())). og Forvent (status (). isOk ()); }
Den første testen vil resultere i en forbudt status på grunn av det manglende CSRF-token, mens den andre vil bli utført riktig.
5. Konklusjon
I denne artikkelen diskuterte vi hvordan du kan forhindre CSRF-angrep ved bruk av Spring Security og Thymeleaf framework.
Den fulle implementeringen av denne veiledningen finner du i GitHub-prosjektet - dette er et formørkelsesbasert prosjekt, så det skal være enkelt å importere og kjøre som det er.