Java embedded jetty is accepting HTTP TRACE method

Michal N. picture Michal N. · Mar 30, 2015 · Viewed 10.2k times · Source

I'm trying to disable HTTP TRACE method in embedded Jetty. In Jetty doc's is info that HTTP trace is disabled by default, but for embedded it is still enabled. I was trying to disable trace as a security constraint as is done in jetty.xml.

    ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY);
    servletHandler.setClassLoader(Server.class.getClassLoader());
    servletHandler.setContextPath("/");
    servletHandler.addEventListener(new ContextLoaderListener());
    servletHandler.addServlet(new ServletHolder(new CXFServlet()), "/*");
    servletHandler.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName());
    servletHandler.setInitParameter("contextConfigLocation", BeansConfig.class.getName());
    servletHandler.setInitParameter("javax.ws.rs.Application", DispatcherConfig.class.getName());

     /*
     * <security-constraint>
     * <web-resource-collection>
     * <web-resource-name>Disable TRACE</web-resource-name>
     * <url-pattern>/</url-pattern>
     * <http-method>TRACE</http-method>
     * </web-resource-collection>
     * <auth-constraint/>
     * </security-constraint>
     */
     Constraint constraint = new Constraint();
     constraint.setName("Disable TRACE");

     ConstraintMapping mapping = new ConstraintMapping();
     mapping.setConstraint(constraint);
     mapping.setMethod("TRACE");
     mapping.setPathSpec("/"); // this did not work same this mapping.setPathSpec("/*");

     ConstraintSecurityHandler securityHandler = (ConstraintSecurityHandler) servletHandler.getSecurityHandler();
     securityHandler.addConstraintMapping(mapping);

Example output from soapUI:

HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 143
Server: Jetty(9.0.6.v20130930)

TRACE / HTTP/1.1
Connection: keep-alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Host: 192.168.33.115
Accept-Encoding: gzip,deflate

Answer

jparker picture jparker · Dec 10, 2015

Extending the Server class and overriding the handle() method worked best for me.

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;

public class MyServer extends Server {

    @Override
    public void handle(HttpChannel<?> connection) throws IOException, ServletException {
        Request request=connection.getRequest();
        Response response=connection.getResponse();

        if ("TRACE".equals(request.getMethod())){
            request.setHandled(true);
            response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
        } else {
            super.handle(connection);
        }
    }
}