diff --git a/allow-list.xml b/allow-list.xml
index 7af26b842..bce70d1e4 100644
--- a/allow-list.xml
+++ b/allow-list.xml
@@ -15,4 +15,28 @@
com.jayway.jsonpath:json-path:2.8.0
CVE-2023-51074
+
+
+ ^pkg:maven/org\.jetbrains\.kotlin/kotlin-stdlib(-jdk7|-jdk8|-common)?@.*$
+ CVE-2020-29582
+
+
+
+ ^pkg:javascript/handlebars@.*$
+ CVE-2026-33916
+ CVE-2026-33937
+ CVE-2026-33938
+ CVE-2026-33939
+ CVE-2026-33940
+ CVE-2026-33941
+ GHSA-7rx3-28cr-v5wh
+ GHSA-442j-39wm-28r2
+
diff --git a/build.gradle b/build.gradle
index ea53f4195..d04d1fe97 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
plugins {
id "io.github.gradle-nexus.publish-plugin" version "1.3.0"
- id "org.owasp.dependencycheck" version "12.1.3"
+ id "org.owasp.dependencycheck" version "12.2.2"
}
ext.projectVersion = '3.3.0-SNAPSHOT'
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 121fcb961..9d612f708 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -11,3 +11,21 @@ dependencies {
implementation 'de.undercouch:gradle-download-task:5.0.2'
implementation 'com.github.ben-manes:gradle-versions-plugin:0.42.0'
}
+
+configurations.all {
+ resolutionStrategy {
+ // owasp-dependencycheck 12.2.2 requires newer versions of several libraries than openapi-generator 6.6.0
+ // provides. Because buildSrc's classpath is the parent classloader for all plugin classloaders, OWASP
+ // inherits buildSrc's older versions via parent-first delegation and fails with NoSuchMethodError.
+ // Force all conflicting libraries to the versions OWASP 12.2.2 requires.
+ force 'com.fasterxml.jackson.core:jackson-databind:2.18.2'
+ force 'com.fasterxml.jackson.core:jackson-core:2.18.2'
+ force 'com.fasterxml.jackson.core:jackson-annotations:2.18.2'
+ force 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.0'
+ force 'org.yaml:snakeyaml:1.33'
+ force 'org.apache.commons:commons-lang3:3.20.0'
+ force 'commons-io:commons-io:2.22.0'
+ force 'org.slf4j:slf4j-api:2.0.17'
+ force 'com.google.guava:guava:33.6.0-jre'
+ }
+}
diff --git a/symphony-bdk-bom/build.gradle b/symphony-bdk-bom/build.gradle
index c64222a30..577b909d0 100644
--- a/symphony-bdk-bom/build.gradle
+++ b/symphony-bdk-bom/build.gradle
@@ -16,13 +16,15 @@ repositories {
dependencies {
// import Spring Boot's BOM
- api platform('org.springframework.boot:spring-boot-dependencies:3.5.11')
+ api platform('org.springframework.boot:spring-boot-dependencies:3.5.14')
// import Jackson's BOM
api platform('com.fasterxml.jackson:jackson-bom:2.18.2')
// import Jersey's BOM
api platform('org.glassfish.jersey:jersey-bom:3.1.9')
// import Log4j's BOM
- api platform('org.apache.logging.log4j:log4j-bom:2.24.2')
+ api platform('org.apache.logging.log4j:log4j-bom:2.26.0')
+ // override Netty (Spring Boot 3.5.14 ships 4.1.132 which is still vulnerable to CVE-2026-41417)
+ api platform('io.netty:netty-bom:4.1.133.Final')
// define all our dependencies versions
constraints {
@@ -55,7 +57,9 @@ dependencies {
api 'org.apache.commons:commons-text:1.14.0'
api 'commons-logging:commons-logging:1.3.5'
api 'com.brsanthu:migbase64:2.2'
- api 'io.jsonwebtoken:jjwt:0.9.1'
+ api 'io.jsonwebtoken:jjwt-api:0.13.0'
+ api 'io.jsonwebtoken:jjwt-impl:0.13.0'
+ api 'io.jsonwebtoken:jjwt-jackson:0.13.0'
api 'org.bouncycastle:bcpkix-jdk18on:1.79'
api 'com.google.code.findbugs:jsr305:3.0.2'
@@ -67,7 +71,7 @@ dependencies {
api 'org.projectreactor:reactor-spring:1.0.1.RELEASE'
api 'org.freemarker:freemarker:2.3.33'
- api 'com.github.jknack:handlebars:4.3.1'
+ api 'com.github.jknack:handlebars:4.5.1'
api 'org.reflections:reflections:0.10.2'
api 'com.tngtech.archunit:archunit-junit5:1.2.1'
diff --git a/symphony-bdk-core/build.gradle b/symphony-bdk-core/build.gradle
index 4a3792ce8..fce96e7c5 100644
--- a/symphony-bdk-core/build.gradle
+++ b/symphony-bdk-core/build.gradle
@@ -47,7 +47,9 @@ dependencies {
implementation 'org.apache.commons:commons-lang3'
implementation 'org.apache.commons:commons-text'
implementation 'com.brsanthu:migbase64'
- implementation 'io.jsonwebtoken:jjwt'
+ implementation 'io.jsonwebtoken:jjwt-api'
+ runtimeOnly 'io.jsonwebtoken:jjwt-impl'
+ runtimeOnly 'io.jsonwebtoken:jjwt-jackson'
implementation 'org.bouncycastle:bcpkix-jdk18on'
api 'com.fasterxml.jackson.core:jackson-databind'
implementation 'io.github.resilience4j:resilience4j-retry'
@@ -130,3 +132,5 @@ apisToGenerate.each { api, path ->
// Duplicated AuthRequest class, we need the one from auth API, so task order matters here
tasks.generateAuth.dependsOn tasks.generateLogin
+// Duplicated SystemApi class, we need the one from agent API (contains v3Health/v3ExtendedHealth), so task order matters here
+tasks.generatePod.dependsOn tasks.generateAgent
diff --git a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/jwt/JwtHelper.java b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/jwt/JwtHelper.java
index 2f8f7b9e1..0c376c27d 100644
--- a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/jwt/JwtHelper.java
+++ b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/jwt/JwtHelper.java
@@ -9,7 +9,6 @@
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
import org.apiguardian.api.API;
import org.bouncycastle.asn1.pkcs.RSAPrivateKey;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
@@ -23,7 +22,6 @@
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
-import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
@@ -65,7 +63,7 @@ public class JwtHelper {
/**
- * Creates a JWT with the provided user name and expiration date, signed with the provided private key.
+ * Creates a JWT with the provided username and expiration date, signed with the provided private key.
*
* @param user the username to authenticate; will be verified by the pod
* @param expiration of the authentication request in milliseconds; cannot be longer than the value defined on the
@@ -75,16 +73,16 @@ public class JwtHelper {
* the public key stored for the user
* @return a signed JWT for a specific user (or subject)
*/
- public static String createSignedJwt(String user, long expiration, Key privateKey) {
+ public static String createSignedJwt(String user, long expiration, PrivateKey privateKey) {
return Jwts.builder()
- .setSubject(user)
- .setExpiration(new Date(System.currentTimeMillis() + expiration))
- .signWith(SignatureAlgorithm.RS512, privateKey)
+ .subject(user)
+ .expiration(new Date(System.currentTimeMillis() + expiration))
+ .signWith(privateKey, Jwts.SIG.RS512)
.compact();
}
/**
- * Creates a RSA Private Key from a PEM String. It supports PKCS#1 and PKCS#8 string formats.
+ * Creates an RSA Private Key from a PEM String. It supports PKCS#1 and PKCS#8 string formats.
*
* @param pemPrivateKey RSA Private Key content
* @return a {@link PrivateKey} instance
@@ -110,18 +108,21 @@ else if (pemPrivateKey.contains(PEM_RSA_PRIVATE_START)) {
/**
* Validates a jwt against a certificate.
*
- * @param jwt
+ * @param jwt string of the jwt to be validated
* @param certificate string of the X.509 certificate content in pem format.
- * @return the content of jwt clain "user" if jwt is successfully validated.
+ * @return the content of jwt claim "user" if jwt is successfully validated.
* @throws AuthInitializationException if certificate or jwt are invalid.
*/
public static UserClaim validateJwt(String jwt, String certificate) throws AuthInitializationException {
final Certificate x509Certificate = parseX509Certificate(certificate);
try {
- final Claims body = Jwts.parser().setSigningKey(x509Certificate.getPublicKey())
- .parseClaimsJws(jwt).getBody();
- return mapper.convertValue(body.get("user"), UserClaim.class);
+ final Claims claims = Jwts.parser()
+ .verifyWith(x509Certificate.getPublicKey())
+ .build()
+ .parseSignedClaims(jwt)
+ .getPayload();
+ return mapper.convertValue(claims.get("user"), UserClaim.class);
} catch (JwtException e) {
throw new AuthInitializationException("Unable to validate JWT", e);
}
diff --git a/symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle b/symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle
index 2ea028923..130379808 100644
--- a/symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle
+++ b/symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle
@@ -16,7 +16,9 @@ dependencies {
implementation 'org.slf4j:slf4j-api'
implementation 'org.apiguardian:apiguardian-api'
- implementation 'io.jsonwebtoken:jjwt'
+ implementation 'io.jsonwebtoken:jjwt-api'
+ runtimeOnly 'io.jsonwebtoken:jjwt-impl'
+ runtimeOnly 'io.jsonwebtoken:jjwt-jackson'
implementation 'org.bouncycastle:bcpkix-jdk18on'
implementation 'commons-io:commons-io'
implementation 'org.apache.commons:commons-lang3'
@@ -42,4 +44,3 @@ dependencies {
testImplementation 'org.mockito:mockito-junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
-