This is an automated email from the ASF dual-hosted git repository.

xvrl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new f32dbd41311 Upgrade pac4j-oidc to 4.5.7 to address CVE-2021-44878 
(#15522)
f32dbd41311 is described below

commit f32dbd41311c3d2ac8c781070c354c12ed462104
Author: Keerthana Srikanth <[email protected]>
AuthorDate: Thu Dec 14 00:14:05 2023 +0530

    Upgrade pac4j-oidc to 4.5.7 to address CVE-2021-44878 (#15522)
    
    * Upgrade org.pac4j:pac4j-oidc to 4.5.5 to address CVE-2021-44878
    * add CVE suppression and notes, since vulnerability scan still shows this 
CVE
    * Add tests to improve coverage
---
 extensions-core/druid-pac4j/pom.xml                |  2 +-
 .../apache/druid/security/pac4j/Pac4jFilter.java   | 17 ++---
 .../druid/security/pac4j/Pac4jSessionStore.java    | 21 +++---
 .../security/pac4j/Pac4jSessionStoreTest.java      | 78 +++++++++++++++++++++-
 licenses.yaml                                      |  6 +-
 owasp-dependency-check-suppressions.xml            |  6 +-
 6 files changed, 104 insertions(+), 26 deletions(-)

diff --git a/extensions-core/druid-pac4j/pom.xml 
b/extensions-core/druid-pac4j/pom.xml
index 7e629f05549..620a926d26a 100644
--- a/extensions-core/druid-pac4j/pom.xml
+++ b/extensions-core/druid-pac4j/pom.xml
@@ -34,7 +34,7 @@
   </parent>
 
   <properties>
-    <pac4j.version>3.8.3</pac4j.version>
+    <pac4j.version>4.5.7</pac4j.version>
 
     <!-- Following must be updated along with any updates to pac4j version -->
     <nimbus.lang.tag.version>1.7</nimbus.lang.tag.version>
diff --git 
a/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jFilter.java
 
b/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jFilter.java
index 4463e43ca29..452a2260946 100644
--- 
a/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jFilter.java
+++ 
b/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jFilter.java
@@ -23,14 +23,15 @@ import org.apache.druid.java.util.common.logger.Logger;
 import org.apache.druid.server.security.AuthConfig;
 import org.apache.druid.server.security.AuthenticationResult;
 import org.pac4j.core.config.Config;
-import org.pac4j.core.context.J2EContext;
+import org.pac4j.core.context.JEEContext;
 import org.pac4j.core.context.session.SessionStore;
 import org.pac4j.core.engine.CallbackLogic;
 import org.pac4j.core.engine.DefaultCallbackLogic;
 import org.pac4j.core.engine.DefaultSecurityLogic;
 import org.pac4j.core.engine.SecurityLogic;
+import org.pac4j.core.exception.http.HttpAction;
 import org.pac4j.core.http.adapter.HttpActionAdapter;
-import org.pac4j.core.profile.CommonProfile;
+import org.pac4j.core.profile.UserProfile;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -47,12 +48,12 @@ public class Pac4jFilter implements Filter
 {
   private static final Logger LOGGER = new Logger(Pac4jFilter.class);
 
-  private static final HttpActionAdapter<String, J2EContext> 
NOOP_HTTP_ACTION_ADAPTER = (int code, J2EContext ctx) -> null;
+  private static final HttpActionAdapter<String, JEEContext> 
NOOP_HTTP_ACTION_ADAPTER = (HttpAction code, JEEContext ctx) -> null;
 
   private final Config pac4jConfig;
-  private final SecurityLogic<String, J2EContext> securityLogic;
-  private final CallbackLogic<String, J2EContext> callbackLogic;
-  private final SessionStore<J2EContext> sessionStore;
+  private final SecurityLogic<String, JEEContext> securityLogic;
+  private final CallbackLogic<String, JEEContext> callbackLogic;
+  private final SessionStore<JEEContext> sessionStore;
 
   private final String name;
   private final String authorizerName;
@@ -88,7 +89,7 @@ public class Pac4jFilter implements Filter
 
     HttpServletRequest httpServletRequest = (HttpServletRequest) 
servletRequest;
     HttpServletResponse httpServletResponse = (HttpServletResponse) 
servletResponse;
-    J2EContext context = new J2EContext(httpServletRequest, 
httpServletResponse, sessionStore);
+    JEEContext context = new JEEContext(httpServletRequest, 
httpServletResponse, sessionStore);
 
     if 
(Pac4jCallbackResource.SELF_URL.equals(httpServletRequest.getRequestURI())) {
       callbackLogic.perform(
@@ -101,7 +102,7 @@ public class Pac4jFilter implements Filter
       String uid = securityLogic.perform(
           context,
           pac4jConfig,
-          (J2EContext ctx, Collection<CommonProfile> profiles, Object... 
parameters) -> {
+          (JEEContext ctx, Collection<UserProfile> profiles, Object... 
parameters) -> {
             if (profiles.isEmpty()) {
               LOGGER.warn("No profiles found after OIDC auth.");
               return null;
diff --git 
a/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jSessionStore.java
 
b/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jSessionStore.java
index 069a4ff2eb9..6c5c57a3319 100644
--- 
a/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jSessionStore.java
+++ 
b/extensions-core/druid-pac4j/src/main/java/org/apache/druid/security/pac4j/Pac4jSessionStore.java
@@ -25,12 +25,12 @@ import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.java.util.common.logger.Logger;
 import org.pac4j.core.context.ContextHelper;
 import org.pac4j.core.context.Cookie;
-import org.pac4j.core.context.Pac4jConstants;
 import org.pac4j.core.context.WebContext;
 import org.pac4j.core.context.session.SessionStore;
 import org.pac4j.core.exception.TechnicalException;
 import org.pac4j.core.profile.CommonProfile;
 import org.pac4j.core.util.JavaSerializationHelper;
+import org.pac4j.core.util.Pac4jConstants;
 
 import javax.annotation.Nullable;
 import java.io.ByteArrayInputStream;
@@ -38,6 +38,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.Map;
+import java.util.Optional;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.GZIPOutputStream;
 
@@ -78,7 +79,7 @@ public class Pac4jSessionStore<T extends WebContext> 
implements SessionStore<T>
 
   @Nullable
   @Override
-  public Object get(WebContext context, String key)
+  public Optional<Object> get(WebContext context, String key)
   {
     final Cookie cookie = ContextHelper.getCookie(context, 
PAC4J_SESSION_PREFIX + key);
     Object value = null;
@@ -86,7 +87,7 @@ public class Pac4jSessionStore<T extends WebContext> 
implements SessionStore<T>
       value = uncompressDecryptBase64(cookie.getValue());
     }
     LOGGER.debug("Get from session: [%s] = [%s]", key, value);
-    return value;
+    return Optional.ofNullable(value);
   }
 
   @Override
@@ -142,7 +143,7 @@ public class Pac4jSessionStore<T extends WebContext> 
implements SessionStore<T>
     if (v != null && !v.isEmpty()) {
       byte[] bytes = StringUtils.decodeBase64String(v);
       if (bytes != null) {
-        return 
javaSerializationHelper.unserializeFromBytes(unCompress(cryptoService.decrypt(bytes)));
+        return 
javaSerializationHelper.deserializeFromBytes(unCompress(cryptoService.decrypt(bytes)));
       }
     }
     return null;
@@ -176,19 +177,19 @@ public class Pac4jSessionStore<T extends WebContext> 
implements SessionStore<T>
   {
     if (value instanceof Map<?, ?>) {
       final Map<String, CommonProfile> profiles = (Map<String, CommonProfile>) 
value;
-      profiles.forEach((name, profile) -> profile.clearSensitiveData());
+      profiles.forEach((name, profile) -> profile.removeLoginData());
       return profiles;
     } else {
       final CommonProfile profile = (CommonProfile) value;
-      profile.clearSensitiveData();
+      profile.removeLoginData();
       return profile;
     }
   }
 
   @Override
-  public SessionStore buildFromTrackableSession(WebContext arg0, Object arg1)
+  public Optional<SessionStore<T>> buildFromTrackableSession(WebContext arg0, 
Object arg1)
   {
-    return null;
+    return Optional.empty();
   }
 
   @Override
@@ -198,9 +199,9 @@ public class Pac4jSessionStore<T extends WebContext> 
implements SessionStore<T>
   }
 
   @Override
-  public Object getTrackableSession(WebContext arg0)
+  public Optional getTrackableSession(WebContext arg0)
   {
-    return null;
+    return Optional.empty();
   }
 
   @Override
diff --git 
a/extensions-core/druid-pac4j/src/test/java/org/apache/druid/security/pac4j/Pac4jSessionStoreTest.java
 
b/extensions-core/druid-pac4j/src/test/java/org/apache/druid/security/pac4j/Pac4jSessionStoreTest.java
index 0349a98a7cc..772bef7ef6c 100644
--- 
a/extensions-core/druid-pac4j/src/test/java/org/apache/druid/security/pac4j/Pac4jSessionStoreTest.java
+++ 
b/extensions-core/druid-pac4j/src/test/java/org/apache/druid/security/pac4j/Pac4jSessionStoreTest.java
@@ -25,15 +25,23 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.pac4j.core.context.Cookie;
 import org.pac4j.core.context.WebContext;
+import org.pac4j.core.profile.CommonProfile;
+import org.pac4j.core.profile.definition.CommonProfileDefinition;
 
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
 
 public class Pac4jSessionStoreTest
 {
+  private static final String COOKIE_PASSPHRASE = "test-cookie-passphrase";
+
   @Test
   public void testSetAndGet()
   {
-    Pac4jSessionStore<WebContext> sessionStore = new 
Pac4jSessionStore("test-cookie-passphrase");
+    Pac4jSessionStore<WebContext> sessionStore = new 
Pac4jSessionStore(COOKIE_PASSPHRASE);
 
     WebContext webContext1 = EasyMock.mock(WebContext.class);
     EasyMock.expect(webContext1.getScheme()).andReturn("https");
@@ -54,7 +62,73 @@ public class Pac4jSessionStoreTest
     WebContext webContext2 = EasyMock.mock(WebContext.class);
     
EasyMock.expect(webContext2.getRequestCookies()).andReturn(Collections.singletonList(cookie));
     EasyMock.replay(webContext2);
+    Assert.assertEquals("value", 
Objects.requireNonNull(sessionStore.get(webContext2, "key")).orElse(null));
+  }
+
+  @Test
+  public void testSetAndGetClearUserProfile()
+  {
+    Pac4jSessionStore<WebContext> sessionStore = new 
Pac4jSessionStore(COOKIE_PASSPHRASE);
+
+    WebContext webContext1 = EasyMock.mock(WebContext.class);
+    EasyMock.expect(webContext1.getScheme()).andReturn("https");
+    Capture<Cookie> cookieCapture = EasyMock.newCapture();
+
+    webContext1.addResponseCookie(EasyMock.capture(cookieCapture));
+    EasyMock.replay(webContext1);
+
+    CommonProfile profile = new CommonProfile();
+    profile.addAttribute(CommonProfileDefinition.DISPLAY_NAME, "name");
+    sessionStore.set(webContext1, "pac4jUserProfiles", profile);
+
+    Cookie cookie = cookieCapture.getValue();
+    Assert.assertTrue(cookie.isSecure());
+    Assert.assertTrue(cookie.isHttpOnly());
+    Assert.assertTrue(cookie.isSecure());
+    Assert.assertEquals(900, cookie.getMaxAge());
+
+
+    WebContext webContext2 = EasyMock.mock(WebContext.class);
+    
EasyMock.expect(webContext2.getRequestCookies()).andReturn(Collections.singletonList(cookie));
+    EasyMock.replay(webContext2);
+    Optional<Object> value = sessionStore.get(webContext2, 
"pac4jUserProfiles");
+    Assert.assertTrue(Objects.requireNonNull(value).isPresent());
+    Assert.assertEquals("name", ((CommonProfile) 
value.get()).getAttribute(CommonProfileDefinition.DISPLAY_NAME));
+  }
+
+  @Test
+  public void testSetAndGetClearUserMultipleProfile()
+  {
+    Pac4jSessionStore<WebContext> sessionStore = new 
Pac4jSessionStore(COOKIE_PASSPHRASE);
+
+    WebContext webContext1 = EasyMock.mock(WebContext.class);
+    EasyMock.expect(webContext1.getScheme()).andReturn("https");
+    Capture<Cookie> cookieCapture = EasyMock.newCapture();
+
+    webContext1.addResponseCookie(EasyMock.capture(cookieCapture));
+    EasyMock.replay(webContext1);
 
-    Assert.assertEquals("value", sessionStore.get(webContext2, "key"));
+    CommonProfile profile1 = new CommonProfile();
+    profile1.addAttribute(CommonProfileDefinition.DISPLAY_NAME, "name1");
+    CommonProfile profile2 = new CommonProfile();
+    profile2.addAttribute(CommonProfileDefinition.DISPLAY_NAME, "name2");
+    Map<String, CommonProfile> profiles = new HashMap<>();
+    profiles.put("profile1", profile1);
+    profiles.put("profile2", profile2);
+    sessionStore.set(webContext1, "pac4jUserProfiles", profiles);
+
+    Cookie cookie = cookieCapture.getValue();
+    Assert.assertTrue(cookie.isSecure());
+    Assert.assertTrue(cookie.isHttpOnly());
+    Assert.assertTrue(cookie.isSecure());
+    Assert.assertEquals(900, cookie.getMaxAge());
+
+
+    WebContext webContext2 = EasyMock.mock(WebContext.class);
+    
EasyMock.expect(webContext2.getRequestCookies()).andReturn(Collections.singletonList(cookie));
+    EasyMock.replay(webContext2);
+    Optional<Object> value = sessionStore.get(webContext2, 
"pac4jUserProfiles");
+    Assert.assertTrue(Objects.requireNonNull(value).isPresent());
+    Assert.assertEquals(2, ((Map<String, CommonProfile>) value.get()).size());
   }
 }
diff --git a/licenses.yaml b/licenses.yaml
index 3eba322b089..cbd0edb8f9e 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -776,7 +776,7 @@ name: pac4j-oidc java security library
 license_category: binary
 module: extensions/druid-pac4j
 license_name: Apache License version 2.0
-version: 3.8.3
+version: 4.5.7
 libraries:
   - org.pac4j: pac4j-oidc
 
@@ -786,7 +786,7 @@ name: pac4j-core java security library
 license_category: binary
 module: extensions/druid-pac4j
 license_name: Apache License version 2.0
-version: 3.8.3
+version: 4.5.7
 libraries:
   - org.pac4j: pac4j-core
 
@@ -837,7 +837,7 @@ name: com.sun.mail javax.mail
 license_category: binary
 module: extensions/druid-pac4j
 license_name: CDDL 1.1
-version: 1.6.1
+version: 1.6.2
 libraries:
   - com.sun.mail: javax.mail
 
diff --git a/owasp-dependency-check-suppressions.xml 
b/owasp-dependency-check-suppressions.xml
index 4d68252dcf4..199087e4497 100644
--- a/owasp-dependency-check-suppressions.xml
+++ b/owasp-dependency-check-suppressions.xml
@@ -331,9 +331,11 @@
   </suppress>
 
   <suppress>
-    <!-- pac4j-core-3.8.3 -->
+    <!-- 4.5.5 is a fixed version as per 
https://nvd.nist.gov/vuln/detail/CVE-2021-44878. -->
+    <!-- However, vulnerability scan still shows this CVE. Pac4j release notes 
mention 5.3.1 as "fully fixed" version. -->
+    <!-- Remove suppression once upgraded to 5.3.1. -->
     <notes><![CDATA[
-   file name: pac4j-core-3.8.3.jar
+   file name: pac4j-core-4.5.7.jar
    ]]></notes>
     <cve>CVE-2021-44878</cve>
   </suppress>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to