Skip to content

Commit d5c62b5

Browse files
Update jjwt version and bump Spring version (#870)
* jjwt dependency update * ci: upgrade org.owasp.dependencycheck to 12.2.2 Fixes CI failure caused by CVE-2026-6785/6786 whose NVD reference URLs exceed the VARCHAR(1000) column limit in the plugin's H2 database schema. * fix: enforce agent-before-pod codegen order to preserve SystemApi health methods * Update build.gradle * ci: set failOnError=false on dependencyCheck to tolerate OWASP 12.2.2 JAR analysis bugs * ci: force commons-lang3/commons-io/slf4j/guava in buildSrc to fix OWASP classloader conflicts * chore(deps): bump Spring Boot/log4j/netty/handlebars to clear CVE-gated scan Bumps in symphony-bdk-bom so dependencyCheckAggregate stays under the CVSS-5 fail gate now that OWASP 12.2.2 analysis runs to completion: - spring-boot-dependencies 3.5.11 -> 3.5.14 (pulls spring-framework 6.2.18, spring-security 6.5.10, tomcat-embed 10.1.54) - log4j-bom 2.24.2 -> 2.26.0 - netty-bom 4.1.133.Final added to override Spring Boot's 4.1.132 (still vulnerable to CVE-2026-41417) - handlebars 4.3.1 -> 4.5.1 (picks up commons-lang3 3.18.0 fix for CVE-2025-48924) Adds two narrow allow-list.xml suppressions for known false positives: kotlin-stdlib CVE-2020-29582 (fixed in 1.4.21; CPE overmatches all 1.x) and the handlebars-v4.7.7.js bundled-resource CVEs (JS engine not used by symphony-bdk-template-handlebars). * ci: remove failOnError=false now that OWASP analyzer crash is fixed The buildSrc classloader fix (f337ba6) made the analyzer run to completion, so the tolerance flag added in 95c8f79 is no longer needed. Reverting to the default (true) so a future analyzer regression fails loudly instead of silently passing with an incomplete report.
1 parent 32cea81 commit d5c62b5

7 files changed

Lines changed: 73 additions & 21 deletions

File tree

allow-list.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,28 @@
1515
<gav>com.jayway.jsonpath:json-path:2.8.0</gav>
1616
<cve>CVE-2023-51074</cve>
1717
</suppress>
18+
<suppress>
19+
<notes><![CDATA[
20+
False positive: CVE-2020-29582 was fixed in Kotlin 1.4.21. The NVD CPE entry matches
21+
all kotlin 1.x versions; we're on 1.9.25 (transitive from Spring Boot) which is not affected.
22+
]]></notes>
23+
<packageUrl regex="true">^pkg:maven/org\.jetbrains\.kotlin/kotlin-stdlib(-jdk7|-jdk8|-common)?@.*$</packageUrl>
24+
<cve>CVE-2020-29582</cve>
25+
</suppress>
26+
<suppress>
27+
<notes><![CDATA[
28+
handlebars.java 4.5.0 still bundles handlebars-v4.7.7.js as a resource. We use the
29+
Java-native handlebars engine (symphony-bdk-template-handlebars), not the JS engine,
30+
so the bundled JS file is not executed and these JS-side CVEs are not reachable.
31+
]]></notes>
32+
<packageUrl regex="true">^pkg:javascript/handlebars@.*$</packageUrl>
33+
<cve>CVE-2026-33916</cve>
34+
<cve>CVE-2026-33937</cve>
35+
<cve>CVE-2026-33938</cve>
36+
<cve>CVE-2026-33939</cve>
37+
<cve>CVE-2026-33940</cve>
38+
<cve>CVE-2026-33941</cve>
39+
<vulnerabilityName>GHSA-7rx3-28cr-v5wh</vulnerabilityName>
40+
<vulnerabilityName>GHSA-442j-39wm-28r2</vulnerabilityName>
41+
</suppress>
1842
</suppressions>

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
plugins {
22
id "io.github.gradle-nexus.publish-plugin" version "1.3.0"
3-
id "org.owasp.dependencycheck" version "12.1.3"
3+
id "org.owasp.dependencycheck" version "12.2.2"
44
}
55

66
ext.projectVersion = '3.3.0-SNAPSHOT'

buildSrc/build.gradle

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,21 @@ dependencies {
1111
implementation 'de.undercouch:gradle-download-task:5.0.2'
1212
implementation 'com.github.ben-manes:gradle-versions-plugin:0.42.0'
1313
}
14+
15+
configurations.all {
16+
resolutionStrategy {
17+
// owasp-dependencycheck 12.2.2 requires newer versions of several libraries than openapi-generator 6.6.0
18+
// provides. Because buildSrc's classpath is the parent classloader for all plugin classloaders, OWASP
19+
// inherits buildSrc's older versions via parent-first delegation and fails with NoSuchMethodError.
20+
// Force all conflicting libraries to the versions OWASP 12.2.2 requires.
21+
force 'com.fasterxml.jackson.core:jackson-databind:2.18.2'
22+
force 'com.fasterxml.jackson.core:jackson-core:2.18.2'
23+
force 'com.fasterxml.jackson.core:jackson-annotations:2.18.2'
24+
force 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.0'
25+
force 'org.yaml:snakeyaml:1.33'
26+
force 'org.apache.commons:commons-lang3:3.20.0'
27+
force 'commons-io:commons-io:2.22.0'
28+
force 'org.slf4j:slf4j-api:2.0.17'
29+
force 'com.google.guava:guava:33.6.0-jre'
30+
}
31+
}

symphony-bdk-bom/build.gradle

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ repositories {
1616

1717
dependencies {
1818
// import Spring Boot's BOM
19-
api platform('org.springframework.boot:spring-boot-dependencies:3.5.11')
19+
api platform('org.springframework.boot:spring-boot-dependencies:3.5.14')
2020
// import Jackson's BOM
2121
api platform('com.fasterxml.jackson:jackson-bom:2.18.2')
2222
// import Jersey's BOM
2323
api platform('org.glassfish.jersey:jersey-bom:3.1.9')
2424
// import Log4j's BOM
25-
api platform('org.apache.logging.log4j:log4j-bom:2.24.2')
25+
api platform('org.apache.logging.log4j:log4j-bom:2.26.0')
26+
// override Netty (Spring Boot 3.5.14 ships 4.1.132 which is still vulnerable to CVE-2026-41417)
27+
api platform('io.netty:netty-bom:4.1.133.Final')
2628

2729
// define all our dependencies versions
2830
constraints {
@@ -55,7 +57,9 @@ dependencies {
5557
api 'org.apache.commons:commons-text:1.14.0'
5658
api 'commons-logging:commons-logging:1.3.5'
5759
api 'com.brsanthu:migbase64:2.2'
58-
api 'io.jsonwebtoken:jjwt:0.9.1'
60+
api 'io.jsonwebtoken:jjwt-api:0.13.0'
61+
api 'io.jsonwebtoken:jjwt-impl:0.13.0'
62+
api 'io.jsonwebtoken:jjwt-jackson:0.13.0'
5963
api 'org.bouncycastle:bcpkix-jdk18on:1.79'
6064
api 'com.google.code.findbugs:jsr305:3.0.2'
6165

@@ -67,7 +71,7 @@ dependencies {
6771
api 'org.projectreactor:reactor-spring:1.0.1.RELEASE'
6872

6973
api 'org.freemarker:freemarker:2.3.33'
70-
api 'com.github.jknack:handlebars:4.3.1'
74+
api 'com.github.jknack:handlebars:4.5.1'
7175
api 'org.reflections:reflections:0.10.2'
7276

7377
api 'com.tngtech.archunit:archunit-junit5:1.2.1'

symphony-bdk-core/build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ dependencies {
4747
implementation 'org.apache.commons:commons-lang3'
4848
implementation 'org.apache.commons:commons-text'
4949
implementation 'com.brsanthu:migbase64'
50-
implementation 'io.jsonwebtoken:jjwt'
50+
implementation 'io.jsonwebtoken:jjwt-api'
51+
runtimeOnly 'io.jsonwebtoken:jjwt-impl'
52+
runtimeOnly 'io.jsonwebtoken:jjwt-jackson'
5153
implementation 'org.bouncycastle:bcpkix-jdk18on'
5254
api 'com.fasterxml.jackson.core:jackson-databind'
5355
implementation 'io.github.resilience4j:resilience4j-retry'
@@ -130,3 +132,5 @@ apisToGenerate.each { api, path ->
130132

131133
// Duplicated AuthRequest class, we need the one from auth API, so task order matters here
132134
tasks.generateAuth.dependsOn tasks.generateLogin
135+
// Duplicated SystemApi class, we need the one from agent API (contains v3Health/v3ExtendedHealth), so task order matters here
136+
tasks.generatePod.dependsOn tasks.generateAgent

symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/jwt/JwtHelper.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import io.jsonwebtoken.Claims;
1010
import io.jsonwebtoken.JwtException;
1111
import io.jsonwebtoken.Jwts;
12-
import io.jsonwebtoken.SignatureAlgorithm;
1312
import org.apiguardian.api.API;
1413
import org.bouncycastle.asn1.pkcs.RSAPrivateKey;
1514
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
@@ -23,7 +22,6 @@
2322
import java.io.StringReader;
2423
import java.nio.charset.StandardCharsets;
2524
import java.security.GeneralSecurityException;
26-
import java.security.Key;
2725
import java.security.KeyFactory;
2826
import java.security.NoSuchAlgorithmException;
2927
import java.security.PrivateKey;
@@ -65,7 +63,7 @@ public class JwtHelper {
6563

6664

6765
/**
68-
* Creates a JWT with the provided user name and expiration date, signed with the provided private key.
66+
* Creates a JWT with the provided username and expiration date, signed with the provided private key.
6967
*
7068
* @param user the username to authenticate; will be verified by the pod
7169
* @param expiration of the authentication request in milliseconds; cannot be longer than the value defined on the
@@ -75,16 +73,16 @@ public class JwtHelper {
7573
* the public key stored for the user
7674
* @return a signed JWT for a specific user (or subject)
7775
*/
78-
public static String createSignedJwt(String user, long expiration, Key privateKey) {
76+
public static String createSignedJwt(String user, long expiration, PrivateKey privateKey) {
7977
return Jwts.builder()
80-
.setSubject(user)
81-
.setExpiration(new Date(System.currentTimeMillis() + expiration))
82-
.signWith(SignatureAlgorithm.RS512, privateKey)
78+
.subject(user)
79+
.expiration(new Date(System.currentTimeMillis() + expiration))
80+
.signWith(privateKey, Jwts.SIG.RS512)
8381
.compact();
8482
}
8583

8684
/**
87-
* Creates a RSA Private Key from a PEM String. It supports PKCS#1 and PKCS#8 string formats.
85+
* Creates an RSA Private Key from a PEM String. It supports PKCS#1 and PKCS#8 string formats.
8886
*
8987
* @param pemPrivateKey RSA Private Key content
9088
* @return a {@link PrivateKey} instance
@@ -110,18 +108,21 @@ else if (pemPrivateKey.contains(PEM_RSA_PRIVATE_START)) {
110108
/**
111109
* Validates a jwt against a certificate.
112110
*
113-
* @param jwt
111+
* @param jwt string of the jwt to be validated
114112
* @param certificate string of the X.509 certificate content in pem format.
115-
* @return the content of jwt clain "user" if jwt is successfully validated.
113+
* @return the content of jwt claim "user" if jwt is successfully validated.
116114
* @throws AuthInitializationException if certificate or jwt are invalid.
117115
*/
118116
public static UserClaim validateJwt(String jwt, String certificate) throws AuthInitializationException {
119117
final Certificate x509Certificate = parseX509Certificate(certificate);
120118

121119
try {
122-
final Claims body = Jwts.parser().setSigningKey(x509Certificate.getPublicKey())
123-
.parseClaimsJws(jwt).getBody();
124-
return mapper.convertValue(body.get("user"), UserClaim.class);
120+
final Claims claims = Jwts.parser()
121+
.verifyWith(x509Certificate.getPublicKey())
122+
.build()
123+
.parseSignedClaims(jwt)
124+
.getPayload();
125+
return mapper.convertValue(claims.get("user"), UserClaim.class);
125126
} catch (JwtException e) {
126127
throw new AuthInitializationException("Unable to validate JWT", e);
127128
}

symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ dependencies {
1616

1717
implementation 'org.slf4j:slf4j-api'
1818
implementation 'org.apiguardian:apiguardian-api'
19-
implementation 'io.jsonwebtoken:jjwt'
19+
implementation 'io.jsonwebtoken:jjwt-api'
20+
runtimeOnly 'io.jsonwebtoken:jjwt-impl'
21+
runtimeOnly 'io.jsonwebtoken:jjwt-jackson'
2022
implementation 'org.bouncycastle:bcpkix-jdk18on'
2123
implementation 'commons-io:commons-io'
2224
implementation 'org.apache.commons:commons-lang3'
@@ -42,4 +44,3 @@ dependencies {
4244
testImplementation 'org.mockito:mockito-junit-jupiter'
4345
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
4446
}
45-

0 commit comments

Comments
 (0)