diff --git a/ChangeLog.md b/ChangeLog.md index e5483bad3c..5af2bd4096 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -16,9 +16,24 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> + +**2025-11-13 Alex O'Ree (alexoree AT apache DOT org)** + +* _3.0.0-git-06_ + +* Dependency Updates + * commons-validator (added) at 1.10.0 + +* [JSPWIKI-1239](https://issues.apache.org/jira/browse/JSPWIKI-1239) New user signup says the email is optional, but does not accept blank since it's already in use by the admin account +* [JSPWIKI-1243](https://issues.apache.org/jira/browse/JSPWIKI-1243 Email validation rouine is incorrect (unicode symbols and more) +* NOJIRA disables and removes the ClearSiteData Servlet Filter which broke CSRF token checks + + + **2025-11-13 Alex O'Ree (alexoree AT apache DOT org)** * _3.0.0-git-05_ + * Dependency Updates * Tomcat updated to 10.1.49 diff --git a/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java b/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java index 93502d19f0..e919bc5fc6 100644 --- a/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java +++ b/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java @@ -69,7 +69,7 @@ public final class Release { *

* If the build identifier is empty, it is not added. */ - public static final String BUILD = "05"; + public static final String BUILD = "06"; /** * This is the generic version string you should use when printing out the version. It is of diff --git a/jspwiki-http/src/main/java/org/apache/wiki/http/filter/ClearSiteDataFilter.java b/jspwiki-http/src/main/java/org/apache/wiki/http/filter/ClearSiteDataFilter.java deleted file mode 100644 index 6477f408cd..0000000000 --- a/jspwiki-http/src/main/java/org/apache/wiki/http/filter/ClearSiteDataFilter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2025 The Apache Software Foundation. - * - * Licensed 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. - */ -package org.apache.wiki.http.filter; - -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.FilterConfig; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * - * Clear-Site-Data: Allows websites to request that browsers clear specific - * browsing data (e.g., cookies, storage, cache) associated with the site. * - */ -public class ClearSiteDataFilter implements Filter { - - private String mode = "\"cookies\", \"storage\""; - - public void init(FilterConfig filterConfig) { - String configMode = filterConfig.getInitParameter("CSDValue"); - if (configMode != null) { - mode = configMode; - } - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletResponse res = (HttpServletResponse) response; - res.addHeader("Clear-Site-Data", mode); - chain.doFilter(request, response); - } - -} diff --git a/jspwiki-main/pom.xml b/jspwiki-main/pom.xml index 223f9860fa..d7e8fd6261 100644 --- a/jspwiki-main/pom.xml +++ b/jspwiki-main/pom.xml @@ -106,6 +106,11 @@ org.apache.commons commons-collections4 + + + commons-validator + commons-validator + org.apache.commons diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java index ceb9f50f3e..5688c78e99 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java @@ -382,15 +382,17 @@ public void validateProfile( final Context context, final UserProfile profile ) } catch( final NoSuchPrincipalException e ) { /* It's clean */ } // It's illegal to use multiple accounts with the same email - try { - otherProfile = getUserDatabase().findByEmail( email ); - if( otherProfile != null && !profile.getUid().equals( otherProfile.getUid() ) // Issue JSPWIKI-1042 - && !profile.equals( otherProfile ) && StringUtils.lowerCase( email ) - .equals( StringUtils.lowerCase( otherProfile.getEmail() ) ) ) { - final Object[] args = { email }; - session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.email.taken" ), args ) ); - } - } catch( final NoSuchPrincipalException e ) { /* It's clean */ } + if (email != null && email.trim().length() > 0) { + try { + otherProfile = getUserDatabase().findByEmail( email ); + if( otherProfile != null && !profile.getUid().equals( otherProfile.getUid() ) // Issue JSPWIKI-1042 + && !profile.equals( otherProfile ) && StringUtils.lowerCase( email ) + .equals( StringUtils.lowerCase( otherProfile.getEmail() ) ) ) { + final Object[] args = { email }; + session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.email.taken" ), args ) ); + } + } catch( final NoSuchPrincipalException e ) { /* It's clean */ } + } } /** {@inheritDoc} */ diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java index fd81abaccc..6bf94833fe 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java @@ -70,7 +70,7 @@ public Outcome execute( final Context context ) throws WikiException { context.getEngine().getManager( UserManager.class ).getUserDatabase().save( profile ); // Send e-mail if user supplied an e-mail address - if ( profile != null && profile.getEmail() != null ) { + if ( profile != null && profile.getEmail() != null && profile.getEmail().length() > 0 ) { try { final InternationalizationManager i18n = context.getEngine().getManager( InternationalizationManager.class ); final String app = context.getEngine().getApplicationName(); diff --git a/jspwiki-main/src/main/java/org/apache/wiki/ui/InputValidator.java b/jspwiki-main/src/main/java/org/apache/wiki/ui/InputValidator.java index 91300e9c86..c644d551ac 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/ui/InputValidator.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/ui/InputValidator.java @@ -27,6 +27,7 @@ Licensed to the Apache Software Foundation (ASF) under one import java.util.ResourceBundle; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.validator.routines.EmailValidator; /** * Provides basic validation services for HTTP parameters. Three standard validators are provided: email address, identifier and @@ -49,7 +50,6 @@ public final class InputValidator { * @since 2.4.82 */ static final Pattern ID_PATTERN = Pattern.compile( "[\\x00\\r\\n\\x0f\"'<>;&\\xff{}]" ); - static final Pattern EMAIL_PATTERN = Pattern.compile( "^[0-9a-zA-Z-_.+]+@([0-9a-zA-Z-_]+\\.)+[a-zA-Z]+$" ); static final Pattern UNSAFE_PATTERN = Pattern.compile( "[\\x00\\r\\n\\x0f\"':<>\\[\\];#&@\\xff{}$%\\\\]" ); private final String m_form; @@ -130,8 +130,7 @@ public boolean validate( final String input, final String label, final int type } return valid; case EMAIL: - matcher = EMAIL_PATTERN.matcher( input ); - valid = matcher.matches(); + valid = EmailValidator.getInstance().isValid(input); if ( !valid ) { final Object[] args = { label }; m_session.addMessage( m_form, MessageFormat.format( rb.getString( "validate.invalidemail" ), args ) ); diff --git a/jspwiki-war/src/main/webapp/Login.jsp b/jspwiki-war/src/main/webapp/Login.jsp index 3574c0b0b2..660d9b4f69 100644 --- a/jspwiki-war/src/main/webapp/Login.jsp +++ b/jspwiki-war/src/main/webapp/Login.jsp @@ -56,7 +56,7 @@ // Are we saving the profile? if( "saveProfile".equals( request.getParameter( "action" ) ) ) { if( !CsrfProtectionFilter.isCsrfProtectedPost( request ) ) { - response.sendRedirect( "/error/Forbidden.html" ); + response.sendRedirect( "error/Forbidden.html" ); return; } diff --git a/jspwiki-war/src/main/webapp/WEB-INF/web.xml b/jspwiki-war/src/main/webapp/WEB-INF/web.xml index 36c98961a9..9a462efed1 100644 --- a/jspwiki-war/src/main/webapp/WEB-INF/web.xml +++ b/jspwiki-war/src/main/webapp/WEB-INF/web.xml @@ -106,14 +106,7 @@ CORPFilter /* - - ClearSiteDataFilter - org.apache.wiki.http.filter.ClearSiteDataFilter - - - ClearSiteDataFilter - /* - + ContentTypeOptionsFilter org.apache.wiki.http.filter.ContentTypeOptionsFilter diff --git a/pom.xml b/pom.xml index 57cfc6fee4..8569bf65cf 100644 --- a/pom.xml +++ b/pom.xml @@ -53,6 +53,7 @@ 3.19.0 3.12.0 1.14.0 + 1.10.0 2.10.9.2 0.64.8 0.60 @@ -172,6 +173,12 @@ commons-net ${commons-net.version} + + + commons-validator + commons-validator + ${commons-validator.version} + com.sun.mail