Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When loading the swagger-ui.html page, a request is made to host:port/ and host:port/csfr

I have a Spring boot 2 application (rest API) and use the Springfox Swagger 2 library, including the UI library. When I open the swagger interface found at http://localhost:8080/swagger-ui.html everything works as expected, but two requests are made that give a 404 result in logger:

http://localhost:8080/ (nothing is mapped to the root of my app)
http://localhost:8080/csfr (this mapping also doesn't exist, but I know it stands for 'cross site forged request')

Apparently Swagger does this because it 'supports' some kind of csfr token checking as explained here. There is an investigation going on for some months now whether these 404 calls can be configured so I'm now pondering implementing the endpoint instead. I'm failing to find information on what to atually immplement. What kind of header/token is swagger expecting, and what will it do with the information in it? Can I use this to make my app (or the swagger endpoint) more secure or accesible? In short: what is the point :)?

like image 883
user1884155 Avatar asked Apr 08 '19 21:04

user1884155


People also ask

How do I get swagger UI in HTML?

Generating HTML documentation using Swagger-ui.Add Swagger-ui dependency - (https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui). This will provide an endpoint at the root url, which provides the Swagger HTML documentation. This will be located at localhost:8080/swagger-ui.

What is the default URL for swagger UI?

By default, Swagger UI is accessible at /q/swagger-ui .

How do I connect Swagger to spring boot?

To enable the Swagger2 in Spring Boot application, you need to add the following dependencies in our build configurations file. For Gradle users, add the following dependencies in your build. gradle file. Now, add the @EnableSwagger2 annotation in your main Spring Boot application.


2 Answers

Let me answer your questions one by one.

Why are the request made to http://localhost:8080/ and http://localhost:8080/csrf?

This is because, Springfox Swagger has by default enabled support for CSRF. What this does is, whenever you try to access any swagger endpoints in your application, it checks for the CSRF token in the below order and attaches it to the request header.

  • CSRF token within your meta tags served at /
  • Endpoint /csrf
  • CSRF token within your cookie

The reason Springfox Swagger attaches the CSRF token is, in case your application has CSRF protection enabled, the requests to the swagger endpoints would fail in case they don't have the CSRF token as part of the header.

What kind of header/token is swagger expecting, and what will it do with the information in it?

As I told earlier, swagger is expecting a CSRF token and it'll attach it to the header of the request when you try to access any swagger endpoints.

Can I use this to make my app (or the swagger endpoint) more secure or accessible?

Enabling CSRF protection within your app would make your app secure from CSRF attacks and not necessarily just by providing the CSRF token to swagger to attach to the header. In case you have enabled CSRF protection within your app, you must provide the CSRF token by any of the above 3 means to access any swagger endpoints within your app. You can read about the use of enabling CSRF protection here.

I'm failing to find information on what to actually implement

There is no use of implementing the CSRF token provision for swagger if you have not enabled CSRF protection within your app, as it would just be redundant. But in case you want to implement the CSRF token provision for swagger you can do it by either of the 3 methods below:

1) CSRF token within your meta tags served at /

<html>
<head>
  <meta name="_csrf" content="${_csrf.token}"/>
  <!-- default header name is X-CSRF-TOKEN -->
  <meta name="_csrf_header" content="${_csrf.headerName}"/>
</head>

This is in case you are using any templating mechanism like JSP, thymeleaf etc.

2) Endpoint /csrf

Define an endpoint /csrf to provide the CSRF token.

  @RequestMapping("/csrf")
  public CsrfToken csrf() {
    //logic to return the CSRF token
  }

3) CSRF token within your cookie

The default cookie name searched for is XSRF-TOKEN, and the default header name returned is X-XSRF-TOKEN. Spring security provides a way of storing the CSRF token in the cookie as required by swagger with the configuration below

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
}

Implementing either of the above 3 would provide swagger with the CSRF token to attach to the request header.

The reference to the above is from the GitHub PR which provided the CSRF support to Springfox swagger and also Spring security documentation which I have linked earlier.

There is currently an open issue regarding the default enabled CSRF support here, and couple of open PRs with the fix #2639 and #2706.

like image 117
Madhu Bhat Avatar answered Sep 16 '22 16:09

Madhu Bhat


Depending on 2) Endpoint /csrf

In my case I disabled WebSecurity until yet and also get the 404 Error Code for /csrf. I fixed that with a simple Controller as mentioned above. Here is my Controller:

@Controller
public class CSRFController {
    @RequestMapping(value = "/csrf", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public ResponseEntity<CsrfToken> getToken(final HttpServletRequest request) {
        return ResponseEntity.ok().body(new HttpSessionCsrfTokenRepository().generateToken(request));
    }

}

If you use that, you need to add the maven dependency for web security:

<dependency>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-web</artifactId>
 </dependency>
like image 40
Fury Avatar answered Sep 18 '22 16:09

Fury