CSRF使用Spring Security进行后端到后端的呼叫

时间:2019-03-29 07:24:20

标签: spring spring-security csrf owasp

我打算在已经构建的应用程序上实施针对CSRF攻击的防护措施(使用Spring Security)。但是,在设计方法时,我面临以下问题:

假设我有两个具有以下端点的API:

  1. / abc
  2. / xyz

方案1 :前端调用 / abc 以及csrf令牌。服务器检查csrf令牌,如果发现正确,则将其传递。一切正常。

方案2 :前端调用 / xyz 以及csrf令牌。服务器检查csrf令牌,如果发现正确,则将其传递。这再次工作正常。

方案3 :API / abc 在内部调用API / xyz 。但是,API / xyz 期望CSRF令牌仅来自前端,因此由于没有csrf令牌, / xyz 失败了。

方案4 :我们也有一些使用我们的API的第三方应用程序(例如支付网关)。他们将如何将CSRF令牌传递给我们的API?

基本上,我想保护我们所有的API免受CSRF攻击,但是我发现很难将csrf令牌从BE传递到BE和从Payment Gateway传递到BE。请帮助我确定我应该遵循的方法,以便我可以轻松涵盖所有这四种情况,并保护应用程序免受任何CSRF攻击。

使用代码示例更新问题

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .requireCsrfProtectionMatcher(new RequestMatcher() {

                @Override
                public boolean matches(HttpServletRequest request) {

                    final HashSet<String> allowedMethods = new HashSet<String>(
                            Arrays.asList("GET", "HEAD", "TRACE", "OPTIONS"));
                    boolean methodCheck = allowedMethods.contains(request.getMethod());
                    if(methodCheck) {
                        return false;
                    }
                    return true;
                }
            });
}

}

API

API 1:

@RestController
public class GetVersion {

@RequestMapping(path="/", method=RequestMethod.GET)
public String getVersion() {
    return "This is a Get Call";
}

}

API 2:

@RestController
public class PostCall2 {
    @RequestMapping(value="/{path}/postcall2",method=RequestMethod.POST)
    public String postCall2(@PathVariable("path") String path) {
        return "This is path: "+path;
    }
}

API 3:

@RestController
public class PostCall1 {

@RequestMapping(path="/{path}/postcall1",method=RequestMethod.POST)
@ResponseBody
public String postCall1(@PathVariable("path") String path) {
    System.out.println("Tring to call /postcall2 from /postcall1");

    final String url = "http://localhost:8080/thisisxyz/postcall2";


    RestTemplate restTemplate = new RestTemplate();
    try {
        String result = restTemplate.postForObject(url, "", String.class);
        System.out.println("Result is: "+result);
        System.out.println("Successfully called /postcall2 from /postcall1");
        return "This is path: "+path;
    }
    catch(HTTPException e) {
        e.printStackTrace();
        return "Failed";
    }
    catch(Exception e) {
        e.printStackTrace();
        return "Failed";
    }
}
}

API 1和API 2可以正常工作,因为可以直接调用它们。但是,API 3试图内部调用API 2,但由于无法向API 2提供CSRF令牌而失败。

0 个答案:

没有答案