From ecf1a9358ee44738f147311fac774542802d5dba Mon Sep 17 00:00:00 2001 From: christophe mangeat Date: Thu, 31 Oct 2024 10:26:55 +0100 Subject: [PATCH] attempt to override a class, remove spring placeholder from substitution web.xml --- pom.xml | 3 +- web/pom.xml | 23 +- .../fao/geonet/web/XFrameOptionsFilter.java | 138 +++++ web/src/main/webapp/WEB-INF/web.xml | 505 ++++++++++++++++++ 4 files changed, 660 insertions(+), 9 deletions(-) create mode 100644 web/src/main/java/org/fao/geonet/web/XFrameOptionsFilter.java create mode 100644 web/src/main/webapp/WEB-INF/web.xml diff --git a/pom.xml b/pom.xml index 20c91d63f6..4712d942cd 100644 --- a/pom.xml +++ b/pom.xml @@ -96,8 +96,7 @@ org.apache.maven.plugins maven-compiler-plugin - 1.11 - 1.11 + 11 true UTF-8 ${fork.javac} diff --git a/web/pom.xml b/web/pom.xml index 78047ff473..c5706d46e3 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -8,7 +8,7 @@ geonetwork 4.4.6-0 - + web war @@ -17,12 +17,12 @@ Web application using maven war overlay functionality to reuse geonetwork war and hnap schema plugin for ${customer}. - + ${project.build.directory}/webapp jetty-env.xml - + @@ -32,12 +32,21 @@ war runtime + + + + org.geonetwork-opensource + gn-web-app + ${project.version} + provided + classes + - + geonetwork - + org.apache.maven.plugins maven-war-plugin @@ -50,7 +59,7 @@ - + org.eclipse.jetty jetty-maven-plugin @@ -71,7 +80,7 @@ --> - + diff --git a/web/src/main/java/org/fao/geonet/web/XFrameOptionsFilter.java b/web/src/main/java/org/fao/geonet/web/XFrameOptionsFilter.java new file mode 100644 index 0000000000..2c207fb64e --- /dev/null +++ b/web/src/main/java/org/fao/geonet/web/XFrameOptionsFilter.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * United Nations (FAO-UN), United Nations World Food Programme (WFP) + * and United Nations Environment Programme (UNEP) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, + * Rome - Italy. email: geonetwork@osgeo.org + */ +package org.fao.geonet.web; + +import org.apache.commons.lang.StringUtils; +import org.fao.geonet.constants.Geonet; +import org.fao.geonet.utils.Log; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Filter to avoid clickjaking attacks. + * + * See https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet. + * + * Modes supported: + * - DENY: prevents any domain from framing the content. + * - SAMEORIGIN, which only allows the current site to frame the content. + * - ALLOW-FROM uri, which permits the specified 'uri' to frame this page. + * Not all browsers support this mode. + * + * Any other value will default to DENY. + * + * Sets X-Frame-Options and Content-Security-Policy (for frame-ancestors) headers. + * + * @author Jose GarcĂ­a + */ +public class XFrameOptionsFilter implements Filter { + private static String MODE_DENY = "DENY"; + private static String MODE_SAMEORIGIN = "SAMEORIGIN"; + private static String MODE_ALLOWFROM = "ALLOW-FROM"; + + private String mode; + private String url; + private String domain; + + public void init(FilterConfig filterConfig) throws ServletException { + mode = filterConfig.getInitParameter("mode"); + url = filterConfig.getInitParameter("url"); + + // Mode: DENY, SAMEORIGIN, ALLOW-FROM. Any other value will default to SAMEORIGIN + if (!mode.equals(MODE_DENY) && !mode.equals(MODE_SAMEORIGIN) && !mode.equals(MODE_ALLOWFROM)) { + mode = MODE_DENY; + } + + // If ALLOW-FROM, make sure a valid url is given, otherwise fallback to deny + if (mode.equals(MODE_ALLOWFROM)) { + if (StringUtils.isEmpty(url)) { + Log.info(Geonet.GEONETWORK, + "XFrameOptions filter url parameter is missing for mode ALLOW-FROM. Setting mode to DENY."); + mode = MODE_DENY; + } else { + domain = url; + } + } + + if (Log.isDebugEnabled(Geonet.GEONETWORK)) { + Log.debug(Geonet.GEONETWORK, String.format( + "XFrameOptions filter initialized. Using mode %s.", getXFrameOptionsValue())); + } + + } + + + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, + FilterChain filterChain) throws IOException, ServletException { + + HttpServletResponse response = (HttpServletResponse) servletResponse; + response.addHeader("X-Frame-Options", getXFrameOptionsValue()); + response.addHeader("Content-Security-Policy", getContentSecurityPolicyFramAncestorsValue()); + + filterChain.doFilter(servletRequest, response); + } + + + public void destroy() { + } + + + /** + * Calculates the X-Frame-Options header value. + * + * @return X-Frame-Options header value. + */ + private String getXFrameOptionsValue() { + if (mode.equals(MODE_ALLOWFROM)) { + return mode + " " + url; + } else { + return mode; + } + } + + + /** + * Calculates the Content-Security-Policy header frame-ancestors value. + * + * @return Content-Security-Policy header frame-ancestors value. + */ + private String getContentSecurityPolicyFramAncestorsValue() { + if (mode.equals(MODE_SAMEORIGIN)) { + return "frame-ancestors 'self'"; + } else if (mode.equals(MODE_ALLOWFROM)) { + return "frame-ancestors " + domain; + } else { + return "frame-ancestors 'none'"; + } + } + +} diff --git a/web/src/main/webapp/WEB-INF/web.xml b/web/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..6c822835dc --- /dev/null +++ b/web/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,505 @@ + + + + + + + ${application.name} + + jeeves.config.springutil.JeevesContextLoaderListener + + + + org.springframework.web.context.request.RequestContextListener + + + + + + + org.apache.jcs.utils.servlet.JCSServletContextListener + + + + characterEncodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + + characterEncodingFilter + /* + + + org.jasig.cas.client.session.SingleSignOutHttpSessionListener + + + + + org.fao.geonet.kernel.security.listener.HttpSessionEventPublisher + + + + + springSecurityFilterChain + jeeves.config.springutil.JeevesDelegatingFilterProxy + + loginService + signin + + + + + springSecurityFilterChain + /* + + + + SessionTimeoutCookieFilter + org.geonetwork.http.SessionTimeoutCookieFilter + + + SessionTimeoutCookieFilter + /srv/* + + + + + cors + org.fao.geonet.web.CORSResponseFilter + + allowedHosts + ${cors.allowedHosts} + + + + cors + /* + + + + + UrlRewriteFilter + org.tuckey.web.filters.urlrewrite.UrlRewriteFilter + + + + + + + + + + logLevel + WARN + + + + + statusEnabled + true + + + + + statusPath + /rewritestatus + + + + UrlRewriteFilter + /* + REQUEST + FORWARD + + + + + XFrameOptionsFilter + + org.fao.geonet.web.XFrameOptionsFilter + + + + mode + ALLOW-FROM + + + url + https://*.admin.ch https://*.cartoriviera.ch https://*.vsgis.ch http://ext.fr.ch http://mapplus.vdf.loc http://mapplus01.vdf.loc https://*.ne.ch https://*.cartolacote.ch https://*.geomapfish.dev + + + + XFrameOptionsFilter + /* + + + + + + resources + org.fao.geonet.resources.ResourceFilter + + + + + + WebResourceOptimizer + + org.fao.geonet.wro4j.GeonetWro4jFilter + + + + WebResourceOptimizer + /static/* + + + + + MetricsRegistryInitializerFilter + org.fao.geonet.monitor.webapp.MetricsRegistryInitializerFilter + + + + + webappMetricsFilter + org.fao.geonet.monitor.webapp.DefaultWebappMetricsFilter + + + + MetricsRegistryInitializerFilter + /* + + + + webappMetricsFilter + /* + + + + resources + /images/logos/* + + + + resources + /config/* + + + + resources + /images/harvesting/* + + + + resources + /xml/schemas/* + + + + resources + /images/statTmp/* + + + + resources + /htmlcache/* + + + + resources + /map/* + + + + + mapfish.print + org.mapfish.print.servlet.MapPrinterServlet + + config + WEB-INF/config-print/print-config.yaml + + + + + mapfish.print + /pdf/* + + + + + monitor + com.yammer.metrics.reporting.AdminServlet + + SHOW_JVM_METRICS + true + + + + criticalHealthChecks + org.fao.geonet.monitor.webapp.GeonetworkHealthCheckServlet + + REGISTRY_ATTRIBUTE_KEY + com.yammer.metrics.reporting.HealthCheckServlet.registry.critical + + + + warningHealthChecks + org.fao.geonet.monitor.webapp.GeonetworkHealthCheckServlet + + REGISTRY_ATTRIBUTE_KEY + com.yammer.metrics.reporting.HealthCheckServlet.registry.warning + + + + expensiveHealthChecks + org.fao.geonet.monitor.webapp.GeonetworkHealthCheckServlet + + REGISTRY_ATTRIBUTE_KEY + com.yammer.metrics.reporting.HealthCheckServlet.registry.expensive + + + + + monitor + /monitor/* + + + criticalHealthChecks + /criticalhealthcheck + + + warningHealthChecks + /warninghealthcheck + + + expensiveHealthChecks + /expensivehealthcheck + + + + gn-servlet + jeeves.server.sources.http.JeevesServlet + + 1 + + + + + HttpProxy + org.fao.geonet.proxy.URITemplateProxyServlet + + targetUri + {url} + + + log + false + + + http.protocol.handle-redirects + true + + + securityMode + ${proxy.securityMode} + + + + HttpProxy + /proxy/* + + + + + MicroServicesProxy + org.fao.geonet.proxy.URITemplateProxyServlet + + targetUri + ${microservices.url} + + + forwardHost + true + + + forwardHostPrefixPath + /api + + + log + false + + + + MicroServicesProxy + /api/* + + + + + + ESFeaturesProxy + org.fao.geonet.proxy.URITemplateProxyServlet + + targetUri + ${es.url}/${es.index.features}/{_} + + + log + false + + + + + + ESFeaturesProxy + /index/features + + + + + HttpDashboardProxy + org.mitre.dsmiley.httpproxy.ProxyServlet + + targetUri + ${kb.url} + + + log + false + + + + HttpDashboardProxy + /dashboards/* + + + + + jolokia-agent + org.jolokia.http.AgentServlet + + policyLocation + classpath:/jolokia-access.xml + + 1 + + + + jolokia-agent + /jolokia/* + + + + + + spring + + jeeves.config.springutil.JeevesDispatcherServlet + + + nodeId + srv + + 2 + + + + spring + /* + + + + COOKIE + 100000 + + true + false + + + + + index.html + +