diff --git a/core/src/main/java/org/apache/struts2/interceptor/StrutsResourceIsolationPolicy.java b/core/src/main/java/org/apache/struts2/interceptor/StrutsResourceIsolationPolicy.java index f1b786b0d0..94cf18b2f0 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/StrutsResourceIsolationPolicy.java +++ b/core/src/main/java/org/apache/struts2/interceptor/StrutsResourceIsolationPolicy.java @@ -56,7 +56,9 @@ private boolean isAllowedTopLevelNavigation(HttpServletRequest request) { String mode = request.getHeader(SEC_FETCH_MODE_HEADER); String dest = request.getHeader(SEC_FETCH_DEST_HEADER); - boolean isSimpleTopLevelNavigation = MODE_NAVIGATE.equalsIgnoreCase(mode) && "GET".equalsIgnoreCase(request.getMethod()); + String method = request.getMethod(); + boolean isSimpleTopLevelNavigation = MODE_NAVIGATE.equalsIgnoreCase(mode) + && ("GET".equalsIgnoreCase(method) || "HEAD".equalsIgnoreCase(method)); boolean isNotObjectOrEmbedRequest = !DEST_EMBED.equalsIgnoreCase(dest) && !DEST_OBJECT.equalsIgnoreCase(dest); return isSimpleTopLevelNavigation && isNotObjectOrEmbedRequest; diff --git a/core/src/test/java/org/apache/struts2/interceptor/FetchMetadataInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/FetchMetadataInterceptorTest.java index 0191c626f2..15bb244e05 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/FetchMetadataInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/FetchMetadataInterceptorTest.java @@ -96,21 +96,18 @@ public void testValidSite() throws Exception { } - public void testValidTopLevelNavigation() throws Exception { - request.addHeader(SEC_FETCH_MODE_HEADER, MODE_NAVIGATE); - request.addHeader(SEC_FETCH_DEST_HEADER, DEST_SCRIPT); - request.setMethod("GET"); - - assertNotEquals("Expected interceptor to accept this request", SC_FORBIDDEN, interceptor.intercept(mai)); - } - - public void testCrossSiteTopLevelGetNavigationAllowed() throws Exception { - request.addHeader(SEC_FETCH_SITE_HEADER, SITE_CROSS_SITE); - request.addHeader(SEC_FETCH_MODE_HEADER, MODE_NAVIGATE); - request.addHeader(SEC_FETCH_DEST_HEADER, DEST_DOCUMENT); - request.setMethod("GET"); + public void testCrossSiteTopLevelGetAndHeadNavigationAllowed() throws Exception { + for (String method : Arrays.asList("GET", "HEAD")) { + request.removeHeader(SEC_FETCH_SITE_HEADER); + request.addHeader(SEC_FETCH_SITE_HEADER, SITE_CROSS_SITE); + request.removeHeader(SEC_FETCH_MODE_HEADER); + request.addHeader(SEC_FETCH_MODE_HEADER, MODE_NAVIGATE); + request.removeHeader(SEC_FETCH_DEST_HEADER); + request.addHeader(SEC_FETCH_DEST_HEADER, DEST_DOCUMENT); + request.setMethod(method); - assertNotEquals("Expected interceptor to accept this request", SC_FORBIDDEN, interceptor.intercept(mai)); + assertNotEquals("Expected interceptor to accept cross-site " + method + " navigation", SC_FORBIDDEN, interceptor.intercept(mai)); + } } public void testCrossSiteNavigationWithUnsafeMethodRejected() throws Exception {