From 80a94a60b5db7f027755bb980c5eca921909506a Mon Sep 17 00:00:00 2001 From: Alexandre Chatiron Date: Thu, 14 Mar 2019 16:44:17 +0100 Subject: [PATCH] [#1300] feat: Define allowed methods used in 'X-HTTP-Method-Override' --- documentation/manual/configuration.textile | 9 +++++++++ framework/src/play/server/PlayHandler.java | 19 +++++++++++++++++-- framework/src/play/server/ServletWrapper.java | 17 ++++++++++++++--- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/documentation/manual/configuration.textile b/documentation/manual/configuration.textile index a55c7124b5..0988c988c3 100644 --- a/documentation/manual/configuration.textile +++ b/documentation/manual/configuration.textile @@ -602,6 +602,15 @@ bc. http.cacheControl=0 Default: @3600@ - set cache expiry to one hour. +h3(#http.allowed.method.override). http.allowed.method.override + +Define allowed methods that will be handled when defined in X-HTTP-Method-Override + +bc. http.allowed.method.override=POST + +Default: none + + h3(#http.exposePlayServer). http.exposePlayServer Disable the HTTP response header that identifies the HTTP server as Play. For example: diff --git a/framework/src/play/server/PlayHandler.java b/framework/src/play/server/PlayHandler.java index 1152bcee07..20cdce69a2 100644 --- a/framework/src/play/server/PlayHandler.java +++ b/framework/src/play/server/PlayHandler.java @@ -26,6 +26,7 @@ import java.security.NoSuchAlgorithmException; import java.text.ParseException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -104,6 +105,10 @@ public class PlayHandler extends SimpleChannelUpstreamHandler { + + + private static final String X_HTTP_METHOD_OVERRIDE = "X-HTTP-Method-Override"; + /** * If true (the default), Play will send the HTTP header * "Server: Play! Framework; ....". This could be a security problem (old @@ -124,6 +129,15 @@ public class PlayHandler extends SimpleChannelUpstreamHandler { private WebSocketServerHandshaker handshaker; + + /** + * Define allowed methods that will be handled when defined in X-HTTP-Method-Override + * You can define allowed method in + * application.conf: http.allowed.method.override=POST,PUT + */ + private static final List allowedHttpMethodOverride = Arrays.asList(Play.configuration.getProperty("http.allowed.method.override", "").split(",")); + + static { try { SHA_1 = MessageDigest.getInstance("SHA1"); @@ -598,8 +612,9 @@ public Request parseRequest(ChannelHandlerContext ctx, HttpRequest nettyRequest, String remoteAddress = getRemoteIPAddress(messageEvent); String method = nettyRequest.getMethod().getName(); - if (nettyRequest.headers().get("X-HTTP-Method-Override") != null) { - method = nettyRequest.headers().get("X-HTTP-Method-Override").intern(); + if (nettyRequest.headers().get(X_HTTP_METHOD_OVERRIDE) != null + && allowedHttpMethodOverride.contains(nettyRequest.headers().get(X_HTTP_METHOD_OVERRIDE).intern())) { + method = nettyRequest.headers().get(X_HTTP_METHOD_OVERRIDE).intern(); } InputStream body = null; diff --git a/framework/src/play/server/ServletWrapper.java b/framework/src/play/server/ServletWrapper.java index ad242ab9b5..8c14a77717 100644 --- a/framework/src/play/server/ServletWrapper.java +++ b/framework/src/play/server/ServletWrapper.java @@ -64,7 +64,17 @@ public class ServletWrapper extends HttpServlet implements ServletContextListene public static final String SERVLET_RES = "__SERVLET_RES"; private static boolean routerInitializedWithContext = false; - + + + private static final String X_HTTP_METHOD_OVERRIDE = "X-HTTP-Method-Override"; + + /** + * Define allowed methods that will be handled when defined in X-HTTP-Method-Override + * You can define allowed method in + * application.conf: http.allowed.method.override=POST,PUT + */ + private static List allowedHttpMethodOverride = Arrays.asList(Play.configuration.getProperty("http.allowed.method.override", "").split(",")); + @Override public void contextInitialized(ServletContextEvent e) { Play.standalonePlayServer = false; @@ -265,8 +275,9 @@ public static Request parseRequest(HttpServletRequest httpServletRequest) throws contentType = "text/html".intern(); } - if (httpServletRequest.getHeader("X-HTTP-Method-Override") != null) { - method = httpServletRequest.getHeader("X-HTTP-Method-Override").intern(); + if (httpServletRequest.getHeader(X_HTTP_METHOD_OVERRIDE) != null && allowedHttpMethodOverride + .contains(httpServletRequest.getHeader(X_HTTP_METHOD_OVERRIDE).intern())) { + method = httpServletRequest.getHeader(X_HTTP_METHOD_OVERRIDE).intern(); } InputStream body = httpServletRequest.getInputStream();