Skip to content

Commit 1f9e929

Browse files
committed
GEODE-10559: Introduction of Security Realm to Security Manager (CVE-2026-23903 remediation) (#7986)
* GEODE-10559: Upgrade Apache Shiro to 2.1.0; migrate APIs (CVE-2026-23903) * GEODE-10559: update integration test resources after Shiro 2.1.0 bump * Build an IniRealm * include shiro * remove shiro * remove shiro * Fix integration test snapshot: remove spurious logback-core entry
1 parent 1da0088 commit 1f9e929

10 files changed

Lines changed: 381 additions & 47 deletions

File tree

build-tools/geode-dependency-management/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class DependencyConstraints {
4949
deps.put("log4j.version", "2.25.3")
5050
deps.put("log4j-slf4j2-impl.version", "2.23.1")
5151
deps.put("micrometer.version", "1.14.0")
52-
deps.put("shiro.version", "1.13.0")
52+
deps.put("shiro.version", "2.1.0")
5353
deps.put("slf4j-api.version", "2.0.17")
5454
deps.put("jakarta.transaction-api.version", "2.0.1")
5555
deps.put("jboss-modules.version", "1.11.0.Final")

geode-assembly/src/integrationTest/resources/assembly_content.txt

Lines changed: 290 additions & 9 deletions
Large diffs are not rendered by default.

geode-assembly/src/integrationTest/resources/expected_jars.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ antlr-runtime
99
asm
1010
asm-commons
1111
asm-tree
12+
bcprov-jdk18on
1213
classgraph
1314
classmate
1415
commons-beanutils
@@ -108,6 +109,8 @@ shiro-crypto-cipher
108109
shiro-crypto-core
109110
shiro-crypto-hash
110111
shiro-event
112+
shiro-hashes-argon
113+
shiro-hashes-bcrypt
111114
shiro-lang
112115
slf4j-api
113116
snakeyaml

geode-assembly/src/integrationTest/resources/gfsh_dependency_classpath.txt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ HikariCP-4.0.3.jar
6666
antlr-2.7.7.jar
6767
istack-commons-runtime-4.1.1.jar
6868
commons-validator-1.7.jar
69-
shiro-core-1.13.0.jar
70-
shiro-config-ogdl-1.13.0.jar
69+
shiro-core-2.1.0.jar
70+
shiro-config-ogdl-2.1.0.jar
7171
commons-beanutils-1.11.0.jar
7272
commons-codec-1.15.jar
7373
commons-collections-3.2.2.jar
@@ -98,13 +98,15 @@ jetty-security-12.0.33.jar
9898
jetty-server-12.0.33.jar
9999
snappy-0.5.jar
100100
jgroups-3.6.20.Final.jar
101-
shiro-cache-1.13.0.jar
102-
shiro-crypto-hash-1.13.0.jar
103-
shiro-crypto-cipher-1.13.0.jar
104-
shiro-config-core-1.13.0.jar
105-
shiro-event-1.13.0.jar
106-
shiro-crypto-core-1.13.0.jar
107-
shiro-lang-1.13.0.jar
101+
shiro-cache-2.1.0.jar
102+
shiro-crypto-hash-2.1.0.jar
103+
shiro-crypto-cipher-2.1.0.jar
104+
shiro-config-core-2.1.0.jar
105+
shiro-event-2.1.0.jar
106+
shiro-crypto-core-2.1.0.jar
107+
shiro-lang-2.1.0.jar
108+
shiro-hashes-argon2-2.1.0.jar
109+
shiro-hashes-bcrypt-2.1.0.jar
108110
jetty-xml-12.0.33.jar
109111
jetty-http-12.0.33.jar
110112
jetty-io-12.0.33.jar
@@ -140,3 +142,4 @@ jboss-logging-3.4.3.Final.jar
140142
classmate-1.5.1.jar
141143
jakarta.el-api-5.0.0.jar
142144
jakarta.inject-api-2.0.1.jar
145+
bcprov-jdk18on-1.82.jar

geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@
2828
import org.apache.commons.lang3.StringUtils;
2929
import org.apache.logging.log4j.Logger;
3030
import org.apache.shiro.SecurityUtils;
31-
import org.apache.shiro.ShiroException;
3231
import org.apache.shiro.UnavailableSecurityManagerException;
32+
import org.apache.shiro.authc.AuthenticationException;
33+
import org.apache.shiro.authz.AuthorizationException;
34+
import org.apache.shiro.config.ConfigurationException;
3335
import org.apache.shiro.session.Session;
3436
import org.apache.shiro.subject.Subject;
3537
import org.apache.shiro.subject.support.SubjectThreadState;
@@ -173,7 +175,7 @@ public Subject login(final Properties credentials) {
173175
currentUser.login(token);
174176
} catch (UnavailableSecurityManagerException e) {
175177
throw new CacheClosedException("Cache is closed.");
176-
} catch (ShiroException e) {
178+
} catch (AuthenticationException | ConfigurationException e) {
177179
logger.info("error logging in: " + token.getPrincipal());
178180
Throwable cause = e.getCause();
179181
if (cause == null) {
@@ -199,7 +201,7 @@ public void logout() {
199201
try {
200202
logger.debug("Logging out " + currentUser.getPrincipal());
201203
currentUser.logout();
202-
} catch (ShiroException e) {
204+
} catch (AuthenticationException e) {
203205
logger.info("error logging out: " + currentUser.getPrincipal());
204206
throw new GemFireSecurityException(e.getMessage(), e);
205207
}
@@ -286,7 +288,7 @@ public void authorize(ResourcePermission context, Subject currentUser) {
286288

287289
try {
288290
currentUser.checkPermission(context);
289-
} catch (ShiroException e) {
291+
} catch (AuthorizationException e) {
290292
String message = currentUser.getPrincipal() + " not authorized for " + context;
291293
logger.info("NotAuthorizedException: {}", message);
292294
throw new NotAuthorizedException(message, e);

geode-core/src/main/java/org/apache/geode/internal/security/SecurityServiceFactory.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_PEER_AUTHENTICATOR;
1919
import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_SHIRO_INIT;
2020

21+
import java.lang.reflect.Method;
2122
import java.util.Properties;
2223

2324
import org.apache.commons.lang3.StringUtils;
@@ -88,9 +89,20 @@ public static SecurityService create(Properties securityProps,
8889

8990
private static boolean isShiroInUse() {
9091
// Don't import Shiro otherwise clients must include on classpath
92+
// Use reflective lookup without initializing the class and be defensive about
93+
// ClassNotFound/NoClassDef/Linkage errors which can occur when the webapp
94+
// classloader does not provide Shiro runtime. If any such error occurs,
95+
// treat Shiro as not in use to avoid hard failures during webapp startup.
9196
try {
92-
return null != Class.forName("org.apache.shiro.SecurityUtils").getMethod("getSecurityManager")
93-
.invoke(null);
97+
ClassLoader cl = Thread.currentThread().getContextClassLoader();
98+
Class<?> securityUtils = Class.forName("org.apache.shiro.SecurityUtils", false, cl);
99+
Method getSecurityManager = securityUtils.getMethod("getSecurityManager");
100+
Object sm = getSecurityManager.invoke(null);
101+
return sm != null;
102+
} catch (ClassNotFoundException e) {
103+
return false;
104+
} catch (LinkageError e) {
105+
return false;
94106
} catch (Exception e) {
95107
return false;
96108
}

geode-core/src/main/java/org/apache/geode/internal/security/shiro/SecurityManagerProvider.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
import org.apache.logging.log4j.Logger;
2020
import org.apache.shiro.SecurityUtils;
2121
import org.apache.shiro.config.Ini;
22-
import org.apache.shiro.config.IniSecurityManagerFactory;
2322
import org.apache.shiro.mgt.DefaultSecurityManager;
2423
import org.apache.shiro.realm.Realm;
24+
import org.apache.shiro.realm.text.IniRealm;
2525
import org.apache.shiro.session.mgt.DefaultSessionManager;
2626
import org.apache.shiro.session.mgt.SessionManager;
2727

@@ -41,14 +41,43 @@ public SecurityManagerProvider() {
4141
public SecurityManagerProvider(String shiroConfig) {
4242
securityManager = null;
4343

44-
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:" + shiroConfig);
45-
// we will need to make sure that shiro uses a case sensitive permission resolver
46-
Ini.Section main = factory.getIni().addSection("main");
44+
// Shiro 2.1.0: IniSecurityManagerFactory is removed. Use Ini and DefaultSecurityManager
45+
// directly. Create an IniRealm from the Ini so realms are properly configured.
46+
Ini ini = new Ini();
47+
ini.loadFromPath("classpath:" + shiroConfig);
48+
Ini.Section main = ini.getSection("main");
49+
if (main == null) {
50+
main = ini.addSection("main");
51+
}
4752
main.put("geodePermissionResolver", GeodePermissionResolver.class.getName());
4853
if (!main.containsKey("iniRealm.permissionResolver")) {
4954
main.put("iniRealm.permissionResolver", "$geodePermissionResolver");
5055
}
51-
shiroManager = factory.getInstance();
56+
57+
// Build an IniRealm from the loaded Ini and set GeodePermissionResolver explicitly.
58+
// Create the realm first, set the GeodePermissionResolver, then attach the Ini
59+
// so the realm parses roles/permissions using our resolver.
60+
IniRealm iniRealm = new IniRealm();
61+
iniRealm.setPermissionResolver(new GeodePermissionResolver());
62+
iniRealm.setIni(ini);
63+
// If the realm exposes an init method, ensure it is initialized (defensive).
64+
try {
65+
java.lang.reflect.Method init = iniRealm.getClass().getMethod("init");
66+
if (init != null) {
67+
init.invoke(iniRealm);
68+
}
69+
} catch (Throwable t) {
70+
// Not critical if method is absent or invocation fails, but log for diagnostics.
71+
logger.debug("IniRealm init invocation failed; continuing without init", t);
72+
}
73+
74+
// Create a DefaultSecurityManager backed by the IniRealm so realms exist.
75+
shiroManager = new DefaultSecurityManager((Realm) iniRealm);
76+
77+
// try to increase global session timeout similar to other provider constructors
78+
if (shiroManager instanceof DefaultSecurityManager) {
79+
increaseShiroGlobalSessionTimeout((DefaultSecurityManager) shiroManager);
80+
}
5281
}
5382

5483

geode-core/src/test/java/org/apache/geode/internal/InternalDataSerializerShiroAcceptListTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@
2525
import java.io.IOException;
2626
import java.util.Properties;
2727

28-
import org.apache.shiro.ShiroException;
2928
import org.apache.shiro.authc.AuthenticationException;
3029
import org.apache.shiro.authz.AuthorizationException;
31-
import org.apache.shiro.codec.CodecException;
3230
import org.apache.shiro.config.ConfigurationException;
3331
import org.apache.shiro.crypto.UnknownAlgorithmException;
3432
import org.apache.shiro.dao.InvalidResourceUsageException;
3533
import org.apache.shiro.env.RequiredTypeException;
36-
import org.apache.shiro.io.SerializationException;
34+
import org.apache.shiro.lang.ShiroException;
35+
import org.apache.shiro.lang.codec.CodecException;
36+
import org.apache.shiro.lang.io.SerializationException;
37+
import org.apache.shiro.lang.util.InstantiationException;
3738
import org.apache.shiro.ldap.UnsupportedAuthenticationMechanismException;
3839
import org.apache.shiro.session.SessionException;
3940
import org.apache.shiro.session.StoppedSessionException;
@@ -91,7 +92,7 @@ public void acceptsExecutionException() throws IOException, ClassNotFoundExcepti
9192

9293
@Test
9394
public void acceptsInstantiationException() throws IOException, ClassNotFoundException {
94-
trySerializingObject(new org.apache.shiro.util.InstantiationException("testing"),
95+
trySerializingObject(new InstantiationException("testing"),
9596
propertiesWithoutFilter());
9697
}
9798

geode-core/src/test/java/org/apache/geode/internal/security/IntegratedSecurityServiceTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424

2525
import java.util.Properties;
2626

27-
import org.apache.shiro.ShiroException;
2827
import org.apache.shiro.UnavailableSecurityManagerException;
28+
import org.apache.shiro.authc.AuthenticationException;
2929
import org.apache.shiro.session.Session;
3030
import org.apache.shiro.subject.Subject;
3131
import org.apache.shiro.subject.SubjectContext;
@@ -53,7 +53,7 @@ public class IntegratedSecurityServiceTest {
5353
private org.apache.shiro.mgt.SecurityManager shiroManager;
5454

5555
private IntegratedSecurityService securityService;
56-
private ShiroException shiroException;
56+
private AuthenticationException shiroException;
5757
private Properties properties;
5858

5959
@Before
@@ -68,7 +68,7 @@ public void before() throws Exception {
6868
when(mockSubject.getPrincipal()).thenReturn("principal");
6969
when(mockSubject.getSession()).thenReturn(mock(Session.class));
7070

71-
shiroException = mock(ShiroException.class);
71+
shiroException = mock(AuthenticationException.class);
7272
properties = new Properties();
7373

7474
securityService = new IntegratedSecurityService(provider, null);
@@ -189,7 +189,7 @@ public void login_when_ShiroException_hasNoCause() throws Exception {
189189
doThrow(shiroException).when(mockSubject).login(any(GeodeAuthenticationToken.class));
190190
assertThatThrownBy(() -> securityService.login(properties))
191191
.isInstanceOf(AuthenticationFailedException.class)
192-
.hasCauseInstanceOf(ShiroException.class)
192+
.hasCauseInstanceOf(AuthenticationException.class)
193193
.hasMessageContaining("Authentication error. Please check your credentials");
194194
}
195195

geode-server-all/src/integrationTest/resources/dependency_classpath.txt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jakarta.enterprise.cdi-api-4.0.1.jar
5656
jakarta.interceptor-api-2.1.0.jar
5757
jakarta.annotation-api-2.1.1.jar
5858
jakarta.transaction-api-2.0.1.jar
59-
shiro-core-1.13.0.jar
59+
shiro-core-2.1.0.jar
6060
jgroups-3.6.20.Final.jar
6161
commons-validator-1.7.jar
6262
fastutil-8.5.8.jar
@@ -82,7 +82,7 @@ lucene-analysis-common-9.12.3.jar
8282
lucene-queryparser-9.12.3.jar
8383
lucene-queries-9.12.3.jar
8484
lucene-core-9.12.3.jar
85-
shiro-config-ogdl-1.13.0.jar
85+
shiro-config-ogdl-2.1.0.jar
8686
commons-beanutils-1.11.0.jar
8787
commons-codec-1.15.jar
8888
commons-collections-3.2.2.jar
@@ -98,13 +98,13 @@ jetty-session-12.0.33.jar
9898
jetty-plus-12.0.33.jar
9999
jetty-security-12.0.33.jar
100100
jetty-server-12.0.33.jar
101-
shiro-cache-1.13.0.jar
102-
shiro-crypto-hash-1.13.0.jar
103-
shiro-crypto-cipher-1.13.0.jar
104-
shiro-config-core-1.13.0.jar
105-
shiro-event-1.13.0.jar
106-
shiro-crypto-core-1.13.0.jar
107-
shiro-lang-1.13.0.jar
101+
shiro-cache-2.1.0.jar
102+
shiro-crypto-hash-2.1.0.jar
103+
shiro-crypto-cipher-2.1.0.jar
104+
shiro-config-core-2.1.0.jar
105+
shiro-event-2.1.0.jar
106+
shiro-crypto-core-2.1.0.jar
107+
shiro-lang-2.1.0.jar
108108
jetty-xml-12.0.33.jar
109109
jetty-http-12.0.33.jar
110110
jetty-io-12.0.33.jar
@@ -140,3 +140,6 @@ jakarta.inject-api-2.0.1.jar
140140
jakarta.validation-api-3.0.2.jar
141141
jboss-logging-3.4.3.Final.jar
142142
classmate-1.5.1.jar
143+
shiro-hashes-argon2-2.1.0.jar
144+
shiro-hashes-bcrypt-2.1.0.jar
145+
bcprov-jdk18on-1.82.jar

0 commit comments

Comments
 (0)