This is an automated email from the ASF dual-hosted git repository. juanpablo pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/jspwiki.git
commit 7c1255e2ec77cb000fc0abd411fc931758784abc Author: Juan Pablo Santos Rodríguez <[email protected]> AuthorDate: Tue Jul 12 22:45:42 2022 +0200 new jspwiki-http module eventually it will contain all JSPWiki servlets, filters, listeners, etc. As for now it only contains a CSRF protection filter --- jspwiki-bom/pom.xml | 6 ++ jspwiki-http/pom.xml | 91 ++++++++++++++++++++++ .../wiki/http/filter/CsrfProtectionFilter.java | 63 +++++++++++++++ .../src/main/resources/META-INF/web-fragment.xml | 34 ++++++++ 4 files changed, 194 insertions(+) diff --git a/jspwiki-bom/pom.xml b/jspwiki-bom/pom.xml index 3b85fea19..06729610f 100644 --- a/jspwiki-bom/pom.xml +++ b/jspwiki-bom/pom.xml @@ -73,6 +73,12 @@ <version>${jspwiki.version}</version> </dependency> + <dependency> + <groupId>org.apache.jspwiki</groupId> + <artifactId>jspwiki-http</artifactId> + <version>${jspwiki.version}</version> + </dependency> + <dependency> <groupId>org.apache.jspwiki</groupId> <artifactId>jspwiki-kendra-searchprovider</artifactId> diff --git a/jspwiki-http/pom.xml b/jspwiki-http/pom.xml new file mode 100644 index 000000000..d3d4fd993 --- /dev/null +++ b/jspwiki-http/pom.xml @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <parent> + <groupId>org.apache.jspwiki</groupId> + <artifactId>jspwiki-builder</artifactId> + <version>2.11.3-SNAPSHOT</version> + </parent> + + <modelVersion>4.0.0</modelVersion> + <artifactId>jspwiki-http</artifactId> + <name>Apache JSPWiki http servlet and filters</name> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>jspwiki-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>jspwiki-util</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-1.2-api</artifactId> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-params</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-junit-jupiter</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/jspwiki-http/src/main/java/org/apache/wiki/http/filter/CsrfProtectionFilter.java b/jspwiki-http/src/main/java/org/apache/wiki/http/filter/CsrfProtectionFilter.java new file mode 100644 index 000000000..aed2ca8e4 --- /dev/null +++ b/jspwiki-http/src/main/java/org/apache/wiki/http/filter/CsrfProtectionFilter.java @@ -0,0 +1,63 @@ +package org.apache.wiki.http.filter; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.wiki.api.core.Engine; +import org.apache.wiki.api.core.Session; +import org.apache.wiki.api.spi.Wiki; + +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.HttpServletRequest; +import java.io.IOException; +import java.io.PrintWriter; + + +/** + * CSRF protection Filter which uses the synchronizer token pattern – an anti-CSRF token is created and stored in the + * user session and in a hidden field on subsequent form submits. At every submit the server checks the token from the + * session matches the one submitted from the form. + */ +public class CsrfProtectionFilter implements Filter { + + private static final Logger LOG = LogManager.getLogger( CsrfProtectionFilter.class ); + + public static final String ANTICSRF_PARAM = "X-XSRF-TOKEN"; + + /** {@inheritDoc} */ + @Override + public void init( final FilterConfig filterConfig ) { + } + + /** {@inheritDoc} */ + @Override + public void doFilter( final ServletRequest request, final ServletResponse response, final FilterChain chain ) throws IOException, ServletException { + if( "POST".equalsIgnoreCase( ( ( HttpServletRequest ) request ).getMethod() ) ) { + final Engine engine = Wiki.engine().find( request.getServletContext(), null ); + final Session session = Wiki.session().find( engine, ( HttpServletRequest ) request ); + if( !session.antiCsrfToken().equals( request.getParameter( ANTICSRF_PARAM ) ) ) { + LOG.error( "Incorrect {} param with value '{}' received for {}", + ANTICSRF_PARAM, request.getParameter( ANTICSRF_PARAM ), ( ( HttpServletRequest ) request ).getPathInfo() ); + final PrintWriter out = response.getWriter(); + out.print("<!DOCTYPE html><html lang=\"en\"><head><title>Fatal problem with JSPWiki</title></head>"); + out.print("<body>"); + out.print("<h1>CSRF injection detected</h1>"); + out.print("<p>A CSRF injection has been detected, so the request has been stopped</p>"); + out.print("<p>Please check your system logs to pinpoint the request origin, someone's trying to mess with your installation.</p>"); + out.print("</body></html>"); + return; + } + } + chain.doFilter( request, response ); + } + + /** {@inheritDoc} */ + @Override + public void destroy() { + } + +} diff --git a/jspwiki-http/src/main/resources/META-INF/web-fragment.xml b/jspwiki-http/src/main/resources/META-INF/web-fragment.xml new file mode 100644 index 000000000..606e68b10 --- /dev/null +++ b/jspwiki-http/src/main/resources/META-INF/web-fragment.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<web-fragment xmlns="http://java.sun.com/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd" + version="3.0"> + <filter> + <filter-name>CsrfProtectionFilter</filter-name> + <filter-class>org.apache.wiki.http.filter.CsrfProtectionFilter</filter-class> + </filter> + + <filter-mapping> + <filter-name>CsrfProtectionFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> +</web-fragment> \ No newline at end of file
