For security purpose regarding my Springboot application, one client is asking for a restriction of the allowed methods
Indeed, although my application only provides GET
and POST
methods, when I run nikto -ssl -h localhost:8181
I get the following messages:
Allowed HTTP Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
OSVDB-397: HTTP method ('Allow' Header): 'PUT' method could allow clients to save files on the web server.
OSVDB-5646: HTTP method ('Allow' Header): 'DELETE' may allow clients to remove files on the web server.
In these circumstances, I am looking for a way to restrict the HTTP methods allowed by my Springboot application and effectively expose only GET
and POST
methods
Thanks for help
CodePudding user response:
You can add your implementation of OncePerRequestFilter
which aims to guarantee a single execution per request dispatch, example as follows:
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class MethodFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (request.getMethod().equals("GET") || request.getMethod().equals("POST")) {
filterChain.doFilter(request, response);
} else {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
}
}
}
This will also disable the OPTIONS
method which returns all possible API options.
CodePudding user response:
Typically, in Spring you develop a custom HandlerInterceptor
and from the preHandle
method, you can block the incoming request by returning false from the method. The framework will then stop doing any additional API calls further down the chain.
public class BlockingHttpMethodInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (HttpMethod.GET.matches(request.getMethod())
|| HttpMethod.POST.matches(request.getMethod())) {
return true;
} else {
response.sendError(HttpStatus.METHOD_NOT_ALLOWED.value());
return false;
}
}
And lastly you can register this handler, potentially providing a strategy on when the handler should be executed.
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BlockingHttpMethodInterceptor())
.addPathPatterns("/**"); // paths that should use the interceptor
}
}