
Application web Java minimale pour reproduire CVE-2022-32532, un contournement d'authentification Apache Shiro RegExPatternMatcher via des caractères de saut de ligne dans les URL.
Ceci est une application Web minimale pour reproduire CVE-2022-32532 (contournement d'authentification Apache Shiro RegExPatternMatcher).
RegExPatternMatcher n'ancrait pas correctement les expressions régulières, ce qui pourrait entraîner un contournement de chemin. Plus précisément, en utilisant la logique de correspondance par défaut de Java, lorsque le symbole . est utilisé dans une expression régulière, les caractères spéciaux \r (%0d) et \n (%0a) sont ignorés. Il est nécessaire d'utiliser explicitement le mode de correspondance basé sur PATTERN.DOTALL pour traiter correctement les caractères \r et \n. Les versions antérieures à shiro-1.9.1 utilisent la logique de correspondance par défaut, ce qui conduit à un contournement de l'authentification.Démarrer l'application
启动ShiroCve202232532Application
L'URL retournant access denied via l'authentification normale de shiro est la suivante :
http://localhost:8080/permit/xxx, le dernier xxx peut être remplacé par n'importe quel caractère.
L'URL retournant success après contournement de l'authentification de shiro est la suivante :
http://localhost:8080/permit/xxx, c'est-à-dire en insérant un saut de ligne \n (%0a) ou un retour chariot \r (%0d) dans le dernier xxx.
Solution
new RegExPatternMatcher() à la ligne 15 de MyFilter et à la ligne 29 de MyShiroFilterFactoryBean par new RegExPatternMatcher191()./*
* 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.
*/
package org.apache.shiro.util;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* {@code PatternMatcher} implementation that uses standard {@link java.util.regex} objects.
*
* @see Pattern
* @since 1.0
*/
public class RegExPatternMatcher implements PatternMatcher {
private static final int DEFAULT = Pattern.DOTALL;
private static final int CASE_INSENSITIVE = DEFAULT | Pattern.CASE_INSENSITIVE;
private boolean caseInsensitive = false;
/**
* Simple implementation that merely uses the default pattern comparison logic provided by the
* JDK.
* <p/>This implementation essentially executes the following:
* <pre>
* Pattern p = Pattern.compile(pattern, Pattern.DOTALL);
* Matcher m = p.matcher(source);
* return m.matches();</pre>
* @param pattern the pattern to match against
* @param source the source to match
* @return {@code true} if the source matches the required pattern, {@code false} otherwise.
*/
public boolean matches(String pattern, String source) {
if (pattern == null) {
throw new IllegalArgumentException("pattern argument cannot be null.");
}
Pattern p = Pattern.compile(pattern, caseInsensitive ? CASE_INSENSITIVE : DEFAULT);
Matcher m = p.matcher(source);
return m.matches();
}
/**
* Returns true if regex match should be case-insensitive.
* @return true if regex match should be case-insensitive.
*/
public boolean isCaseInsensitive() {
return caseInsensitive;
}
/**
* Adds the Pattern.CASE_INSENSITIVE flag when compiling patterns.
* @param caseInsensitive true if patterns should match case-insensitive.
*/
public void setCaseInsensitive(boolean caseInsensitive) {
this.caseInsensitive = caseInsensitive;
}
}