Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to intercept/disable HTTP Trace Method in Java SpringBoot

In order to disable insecure http methods, I have used a request filter

@Component
public class MethodFilter extends OncePerRequestFilter {

    private final String[] allowedMethods = new String[]{"PUT", "POST", "GET", "OPTIONS"};

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        if (Arrays.stream(allowedMethods).noneMatch(x -> x.equals(request.getMethod()))) {
            response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
        }
        filterChain.doFilter(request, response);
    }
}

This works perfectly for all methods except "TRACE". For trace method, this filter is not invoked and I get a echo back of the all the headers in response body

TRACE /error HTTP/1.1
my-header: test
accept: */*
host: localhost:8087
accept-encoding: gzip, deflate, br
connection: keep-alive

For all other methods which are not in the list I get result as expected

{
    "timestamp": "2021-11-03T11:49:48.545+0000",
    "status": 405,
    "error": "Method Not Allowed",
    "message": "DELETE method is not allowed",
    "path": "/test"
}

Referring to doc it seems, trace requests are sent to frameworkservlet and processed there itself. Have tried setting spring.mvc.dispatch-trace-request=true but now the responses are clubbed like this (filter still not invoked)

{
    "timestamp": "2021-11-03T11:49:48.545+0000",
    "status": 405,
    "error": "Method Not Allowed",
    "message": "TRACE method is not allowed",
    "path": "/test"
}TRACE /error HTTP/1.1
my-header: test
accept: */*
host: localhost:8087
accept-encoding: gzip, deflate, br
connection: keep-alive

My question is how can I make TRACE response as same as the other requests ?

Note: The solution in this thread did not work for me.

Edit: Found the solution. An interceptor does the trick instead of a filter

@Component
public class MethodInterceptor implements HandlerInterceptor {

    private final String[] allowedMethods = new String[]{"PUT", "POST", "GET", "OPTIONS"};

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (Arrays.stream(allowedMethods).noneMatch(x -> x.equals(request.getMethod()))) {
            response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
            response.setHeader("Allow", "PUT, POST, GET, OPTIONS");
            response.setContentType("message/http");
            response.getWriter().println(request.getMethod() + " method not allowed");
            response.getWriter().flush();
            return false;
        }
        return true;
    }
}

And add the interceptor via config file

    @Configuration
    public class InterceptorConfiguration implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new MethodInterceptor());
        }
    }

This needs to be used in conjunction with spring.mvc.dispatch-trace-request=true

like image 613
SpartanX1 Avatar asked Mar 12 '26 17:03

SpartanX1


1 Answers

What if you try configuring Spring Security for it ... The approach with writing the filter manually, it feels a bit low level ...

@Override
protected void configure(HttpSecurity http) throws Exception
{
     http
    .authorizeRequests()
       // You can actually disable other methods here as well
      .antMatchers(HttpMethod.TRACE,"/**").denyAll()
    .httpBasic();
}

If this does not work for you ... according to the docs it says

Note that HttpServlets default TRACE processing will be applied
in any case if your controllers happen to not generate a response
of content type 'message/http' (as required for a TRACE response)

Why don't you try setting content type header to message/http when responding to a TRACE request in your filter ?

Another option is disabling this in the dispatcher servlet

like image 188
Arthur Klezovich Avatar answered Mar 15 '26 06:03

Arthur Klezovich



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!