Skip to content
24 changes: 24 additions & 0 deletions allow-list.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,28 @@
<gav>com.jayway.jsonpath:json-path:2.8.0</gav>
<cve>CVE-2023-51074</cve>
</suppress>
<suppress>
<notes><![CDATA[
False positive: CVE-2020-29582 was fixed in Kotlin 1.4.21. The NVD CPE entry matches
all kotlin 1.x versions; we're on 1.9.25 (transitive from Spring Boot) which is not affected.
]]></notes>
<packageUrl regex="true">^pkg:maven/org\.jetbrains\.kotlin/kotlin-stdlib(-jdk7|-jdk8|-common)?@.*$</packageUrl>
<cve>CVE-2020-29582</cve>
</suppress>
<suppress>
<notes><![CDATA[
handlebars.java 4.5.0 still bundles handlebars-v4.7.7.js as a resource. We use the
Java-native handlebars engine (symphony-bdk-template-handlebars), not the JS engine,
so the bundled JS file is not executed and these JS-side CVEs are not reachable.
]]></notes>
<packageUrl regex="true">^pkg:javascript/handlebars@.*$</packageUrl>
<cve>CVE-2026-33916</cve>
<cve>CVE-2026-33937</cve>
<cve>CVE-2026-33938</cve>
<cve>CVE-2026-33939</cve>
<cve>CVE-2026-33940</cve>
<cve>CVE-2026-33941</cve>
<vulnerabilityName>GHSA-7rx3-28cr-v5wh</vulnerabilityName>
<vulnerabilityName>GHSA-442j-39wm-28r2</vulnerabilityName>
</suppress>
</suppressions>
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
18 changes: 18 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}
}
12 changes: 8 additions & 4 deletions symphony-bdk-bom/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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'

Expand All @@ -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'
Expand Down
6 changes: 5 additions & 1 deletion symphony-bdk-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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);
}
Expand Down
5 changes: 3 additions & 2 deletions symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -42,4 +44,3 @@ dependencies {
testImplementation 'org.mockito:mockito-junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

Loading