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' } -