From 846d6919b8645be922700f877e4c83708c263bb5 Mon Sep 17 00:00:00 2001 From: Vikram Date: Tue, 17 Mar 2026 14:07:09 +0530 Subject: [PATCH 1/5] fix: improve security scan to use CycloneDX SBOM for accurate vulnerability detection Switch from scanning Gradle cache dir to generating a proper CycloneDX SBOM via the cyclonedx-gradle-plugin and feeding it to Grype. This ensures shaded/fat JARs (e.g. testsigma-java-sdk) have their bundled transitive dependencies fully resolved and reported, closing the gap where 'dir:' scanning missed embedded libs. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/security-scan.yml | 17 ++++++++++------- build.gradle | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 3e37129..afe7869 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -16,19 +16,20 @@ jobs: java-version: '11' distribution: 'zulu' - - name: Download dependencies - run: ./gradlew dependencies --no-daemon + - name: Generate CycloneDX SBOM + # Resolves all transitive dependencies and produces build/reports/bom.json + run: ./gradlew cyclonedxBom --no-daemon - name: Install Grype run: curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin - name: Run Grype vulnerability scanner run: | - GRADLE_CACHE="$HOME/.gradle/caches/modules-2/files-2.1" - echo "Scanning Gradle cache: $(find $GRADLE_CACHE -name '*.jar' | wc -l) JARs found" - grype "dir:$GRADLE_CACHE" \ + echo "=== Vulnerability table ===" + grype "sbom:build/reports/bom.json" \ --output table - grype "dir:$GRADLE_CACHE" \ + + grype "sbom:build/reports/bom.json" \ --output sarif > grype-results.sarif - name: Upload scan results as artifact @@ -36,4 +37,6 @@ jobs: if: always() with: name: grype-scan-results - path: 'grype-results.sarif' + path: | + grype-results.sarif + build/reports/bom.json diff --git a/build.gradle b/build.gradle index 0d40c35..d461ce2 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,7 @@ plugins { id 'maven-publish' id 'signing' id 'com.vanniktech.maven.publish' version '0.34.0' + id 'org.cyclonedx.bom' version '1.10.0' } repositories { From 7a9fa46cdb2f603496633f0eb2d9155533d29086 Mon Sep 17 00:00:00 2001 From: Vikram Date: Tue, 17 Mar 2026 17:03:08 +0530 Subject: [PATCH 2/5] fix: enhance security scan with JAR collection, syft SBOM, and Trivy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the Gradle CycloneDX plugin approach with a proper multi-stage scan: - Add Gradle init-script step that copies runtimeClasspath JARs into .dep-jars/ inside the workspace (no cache-path guessing, workspace-mounted so syft sees them) - Add scan-target fallback step that warns and falls back to source scan if no JARs - Switch SBOM generation to anchore/sbom-action (syft), which reads META-INF/maven/*/pom.properties from each JAR — correctly surfaces bundled dependencies inside fat/shaded JARs (e.g. testsigma-java-sdk's embedded jackson-databind 2.12.1 that the Gradle plugin missed) - Feed the syft SBOM into both Grype (SARIF) and Trivy (JSON) for dual-scanner coverage - Remove org.cyclonedx.bom Gradle plugin; SBOM generation is now CI-only Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/security-scan.yml | 124 +++++++++++++++++++++++++--- build.gradle | 1 - 2 files changed, 111 insertions(+), 14 deletions(-) diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index afe7869..f460f96 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -3,34 +3,131 @@ name: Security Vulnerability Scan on: workflow_dispatch: +env: + JAVA_VERSION: '11' + jobs: grype-scan: + name: "Java/Gradle Vulnerability Scan" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v4 - - name: Setup Java version - uses: actions/setup-java@v3 + - name: Setup Java + uses: actions/setup-java@v4 with: - java-version: '11' + java-version: ${{ env.JAVA_VERSION }} distribution: 'zulu' - - name: Generate CycloneDX SBOM - # Resolves all transitive dependencies and produces build/reports/bom.json - run: ./gradlew cyclonedxBom --no-daemon + # Collect all runtime dependency JARs into .dep-jars/ inside the workspace. + # + # A one-off Gradle init script copies the runtimeClasspath configuration + # directly — no cache-path guessing, works with any layout. + # Keeping JARs inside $GITHUB_WORKSPACE is critical: anchore/sbom-action + # mounts only the workspace into its container, so any path outside it + # is silently invisible to syft. + - name: Collect runtime dependency JARs + id: collect-deps + continue-on-error: true + run: | + mkdir -p .dep-jars + [ -f "gradlew" ] && chmod +x gradlew + GRADLEW=$([ -f "gradlew" ] && echo "./gradlew" || echo "gradle") + + # Init script: copies runtimeClasspath (or nearest equivalent) for + # every subproject into .dep-jars/ without touching build.gradle. + # Written with printf to avoid the '<<' heredoc operator, which + # GitHub's YAML parser misreads as a merge key inside a block scalar. + printf '%s\n' \ + 'allprojects {' \ + " tasks.register('_copyDepsForScan') {" \ + ' doLast {' \ + " def cfg = project.configurations.findByName('runtimeClasspath') ?:" \ + " project.configurations.findByName('runtime') ?:" \ + " project.configurations.findByName('compileClasspath')" \ + ' if (cfg) {' \ + " def destDir = rootProject.file('.dep-jars')" \ + ' destDir.mkdirs()' \ + ' try {' \ + ' cfg.resolvedConfiguration.lenientConfiguration.artifacts' \ + ' .findAll { art ->' \ + " art.file.name.endsWith('.jar') &&" \ + " !art.file.name.endsWith('-sources.jar') &&" \ + " !art.file.name.endsWith('-javadoc.jar')" \ + ' }' \ + ' .each { art ->' \ + ' def dest = new File(destDir, art.file.name)' \ + ' java.nio.file.Files.copy(' \ + ' art.file.toPath(),' \ + ' dest.toPath(),' \ + ' java.nio.file.StandardCopyOption.REPLACE_EXISTING' \ + ' )' \ + ' }' \ + ' } catch (ignored) {}' \ + ' }' \ + ' }' \ + ' }' \ + '}' \ + > /tmp/copy-deps.init.gradle + + $GRADLEW --no-daemon \ + --init-script /tmp/copy-deps.init.gradle \ + _copyDepsForScan 2>/dev/null || \ + $GRADLEW --no-daemon \ + --init-script /tmp/copy-deps.init.gradle \ + :_copyDepsForScan 2>/dev/null || true + + JAR_COUNT=$(find .dep-jars -maxdepth 1 -name '*.jar' | wc -l | tr -d ' ') + echo "jar_count=$JAR_COUNT" >> "$GITHUB_OUTPUT" + echo "Collected $JAR_COUNT runtime JARs into .dep-jars/" + + - name: Resolve scan target + id: scan-target + run: | + JAR_COUNT="${{ steps.collect-deps.outputs.jar_count }}" + if [ "${JAR_COUNT:-0}" -gt 0 ]; then + echo "ref=.dep-jars" >> "$GITHUB_OUTPUT" + echo "Scan target: .dep-jars (${JAR_COUNT} runtime JARs)" + else + echo "ref=." >> "$GITHUB_OUTPUT" + echo "::warning::No runtime JARs collected — falling back to source scan (results may be incomplete)" + fi + + # Generate SBOM via syft (anchore/sbom-action). + # syft reads META-INF/maven/*/pom.properties from each JAR to extract + # precise GAV coordinates, correctly surfacing bundled libraries inside + # fat/shaded JARs (e.g. testsigma-java-sdk's embedded jackson-databind). + # This is more reliable than the Gradle CycloneDX plugin, which only + # sees declared dependencies and misses shaded transitive content. + - name: Generate Java SBOM (syft) + uses: anchore/sbom-action@v0 + with: + path: ${{ steps.scan-target.outputs.ref }} + format: cyclonedx-json + output-file: sbom-java.cdx.json + artifact-name: sbom-java.cdx.json - name: Install Grype run: curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin - name: Run Grype vulnerability scanner run: | - echo "=== Vulnerability table ===" - grype "sbom:build/reports/bom.json" \ - --output table + echo "=== Grype vulnerability table ===" + grype "sbom:sbom-java.cdx.json" --output table - grype "sbom:build/reports/bom.json" \ - --output sarif > grype-results.sarif + grype "sbom:sbom-java.cdx.json" --output sarif > grype-results.sarif + + - name: Trivy Java scan (JSON) + uses: aquasecurity/trivy-action@0.34.2 + with: + scan-type: sbom + scan-ref: sbom-java.cdx.json + format: json + output: trivy-java.json + severity: LOW,MEDIUM,HIGH,CRITICAL + exit-code: "0" - name: Upload scan results as artifact uses: actions/upload-artifact@v4 @@ -39,4 +136,5 @@ jobs: name: grype-scan-results path: | grype-results.sarif - build/reports/bom.json + sbom-java.cdx.json + trivy-java.json diff --git a/build.gradle b/build.gradle index d461ce2..0d40c35 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,6 @@ plugins { id 'maven-publish' id 'signing' id 'com.vanniktech.maven.publish' version '0.34.0' - id 'org.cyclonedx.bom' version '1.10.0' } repositories { From cdb6dfc054ed5aecf1c8a787a21ecea7b9c68e18 Mon Sep 17 00:00:00 2001 From: Vikram Date: Tue, 17 Mar 2026 17:35:51 +0530 Subject: [PATCH 3/5] fix: upgrade vulnerable dependencies and bump version to 1.2.25_cloud MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - org.json:json 20160810 → 20231013 (CVE-2022-45688, CVE-2023-5072) - org.testng:testng 7.4.0 → 7.7.0 (CVE-2022-4065) - org.apache.commons:commons-lang3 3.12.0 → 3.18.0 (CVE-2025-48924) Co-Authored-By: Claude Sonnet 4.6 --- build.gradle | 8 ++++---- gradle.properties | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 0d40c35..f01f595 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ repositories { } group = 'com.testsigma' -version = '1.2.24_cloud' +version = '1.2.25_cloud' description = 'Testsigma Java SDK' java.sourceCompatibility = JavaVersion.VERSION_11 @@ -37,9 +37,9 @@ dependencies { implementation 'org.seleniumhq.selenium:selenium-api:4.33.0' implementation 'org.seleniumhq.selenium:selenium-java:4.33.0' implementation 'io.appium:java-client:9.4.0' - implementation 'org.apache.commons:commons-lang3:3.12.0' - implementation 'org.testng:testng:7.4.0' - implementation 'org.json:json:20160810' + implementation 'org.apache.commons:commons-lang3:3.18.0' + implementation 'org.testng:testng:7.7.0' + implementation 'org.json:json:20231013' implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.0' annotationProcessor 'org.projectlombok:lombok:1.18.20' implementation 'org.apache.httpcomponents:httpclient:4.5.14' diff --git a/gradle.properties b/gradle.properties index f37a866..16e47e3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ signAllPublications=true GROUP=com.testsigma POM_ARTIFACT_ID=testsigma-java-sdk -VERSION_NAME=1.2.24_cloud +VERSION_NAME=1.2.25_cloud POM_NAME=Testsigma Java SDK POM_DESCRIPTION=Testsigma Java SDK From da5f19bfe9c790b9159de8307f3e217517f1f7b4 Mon Sep 17 00:00:00 2001 From: Vikram Date: Tue, 17 Mar 2026 20:02:14 +0530 Subject: [PATCH 4/5] Updated testng version to 7.10.2 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index f01f595..e2e283c 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ repositories { } group = 'com.testsigma' -version = '1.2.25_cloud' +version = '1.2.26_cloud' description = 'Testsigma Java SDK' java.sourceCompatibility = JavaVersion.VERSION_11 @@ -38,7 +38,7 @@ dependencies { implementation 'org.seleniumhq.selenium:selenium-java:4.33.0' implementation 'io.appium:java-client:9.4.0' implementation 'org.apache.commons:commons-lang3:3.18.0' - implementation 'org.testng:testng:7.7.0' + implementation 'org.testng:testng:7.10.2' implementation 'org.json:json:20231013' implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.0' annotationProcessor 'org.projectlombok:lombok:1.18.20' From 5173b2b3cdb5986b6fbb0485cadbaea14286011f Mon Sep 17 00:00:00 2001 From: Vikram Date: Tue, 17 Mar 2026 20:05:44 +0530 Subject: [PATCH 5/5] version updated to 1.2.26_cloud --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 16e47e3..f47f466 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ signAllPublications=true GROUP=com.testsigma POM_ARTIFACT_ID=testsigma-java-sdk -VERSION_NAME=1.2.25_cloud +VERSION_NAME=1.2.26_cloud POM_NAME=Testsigma Java SDK POM_DESCRIPTION=Testsigma Java SDK