一、什麼是CSRF
CSRF(Cross-site request forgery)跨站請求偽造,是黑客利用受害者已經登錄了網站的身份憑證,通過偽造請求的方式,以受害者的名義對伺服器發起非法操作請求的攻擊方式。
常見攻擊場景包括:在網站中隱藏惡意腳本,在用戶登錄網站的時候讓用戶自動執行,或者是通過誘導用戶點擊特定鏈接進行攻擊等等。
如不進行防護措施,CSRF攻擊將會導致伺服器誤認為是受害者主動發起的操作,從而對伺服器及用戶造成很高的風險。
二、為什麼需要進行CSRF防護
在Spring Security中,它內置了對CSRF(跨站點請求偽造)的保護機制。 這個保護機制建立在cookie上,它是一種偽隨機生成令牌(CSRF-Token)和伺服器端生成的令牌(Synchronizer Token)。 該令牌與session ID一起工作,用於在伺服器端驗證發出的請求是否來自該用戶。
如果我們把CSRF攻擊稱為 「帶著瀏覽器上的Cookie發起攻擊」 ,那麼我們可以對Spring Boot進行必要的CSRF防護。
三、Spring Boot中如何開啟CSRF防護
實現CSRF防護的唯一方法是發送包含正確令牌的請求。使用SPRING_SECURITY_CSRF_TOKEN的欄位是本文中一個意義重大的參數。
CSRF防護的關鍵是:在表單或AJAX請求中需要添加CSRF令牌。這要求表單以某種方式從服務獲取令牌。 Spring Security支持兩種方式:cookie方式和表單向服務請求(token方式)。
我們下面分別介紹兩種實現方式。
四、方式一:cookie方式
在Spring中,通過在CSRF令牌中添加Cookies來實現一種機制來防止CSRF攻擊。 在默認情況下, cookie方式為Spring Boot的CSRF防護機制。
@Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); } }
在過程中,只有設置appropriate CsrfTokenRepository後, Spring Security 才會自動包含一個名為_XSRF-TOKEN的cookie。當客戶端作為下一步訪問伺服器時,將從cookie和自定義的HTTP頭中提取和驗證CSRF令牌。 此外,在使用JavaScript庫jQuery或AngularJS時,需要一些額外的工作,以便在發出POST請求時自動添加名稱為X-XSRF-TOKEN的請求頭,並引用前面從cookie中獲取的值。
五、方式二:token方式
Spring Security 還支持直接將CSRF令牌放入請求(表單以及 AJAX 請求)中以進行Token方式更具體,它需要在服務端生成csrf令牌,將其放置在input hidden或者請求header中,在客戶端發送ajax請求或者表單請求時帶上csrf token,這樣伺服器校驗到伺服器csrf令牌後才允許請求訪問。
@Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); } @Bean public CsrfTokenRepository csrfTokenRepository() { HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); repository.setHeaderName("X-XSRF-TOKEN"); return repository; } }
前端需要獲取XSRF-TOKEN,並將其放入Http請求中。示例代碼如下:
// 獲取XSRF-TOKEN var csrfToken = $("meta[name='_csrf']").attr("content"); $.ajax({ type: "GET", url: "your-url", beforeSend: function (request) { request.setRequestHeader("X-XSRF-TOKEN", csrfToken); }, data: formData, success: function (result) { //do something }, error: function (error) { //do something }, });
六、綜合示例
下面是一個Spring Boot項目中完整的CSRF防護示例代碼:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll() .and() .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); } @Bean public CsrfTokenRepository csrfTokenRepository() { HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); repository.setHeaderName("X-XSRF-TOKEN"); return repository; } }
七、小結
CSRF攻擊具有很高的風險,因此在開發Web應用程序時,必須採取適當的安全措施來保護自己的應用程序。 在Spring Boot中,您可以使用默認的Cookie方式或在cookie和請求header中添加CSRF令牌,以增強應用程序的安全性。
原創文章,作者:ENPXK,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/370392.html