From 3a4f7863a0e6fc5f2fdf95dc34d5f119564a5954 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 31 Jul 2025 09:10:30 +0000 Subject: [PATCH 01/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 22c6f030..d95a9412 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d2436e1fef7dd4841a003697702e52e2cdc3f3fba74e2196cebe5d7992f9d4f -size 76206264 +oid sha256:a4ca697ea3e79160e94e885228c418d89e0a4eef9acae7c54f30ddab222c24d1 +size 76255416 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index b7b9337d..ef897526 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e41b066ccc5dd4281a134518b3ece5ac6c17f229c9a7844493371ac3936a94a4 +oid sha256:a9d748161f3fc39b71dcf33a69cf4143134359427eed7756c1d49bf262571cf1 size 72745144 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index e73d13f2..db1af770 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4764f25769b820906cf09c6b3281f2b1df7c021f9063aef983f2aac0c48e39bc -size 153324992 +oid sha256:cd662a538ae11c59010aef4e0fdea48e10f838aad5e3b75fc08112c089a4bbfe +size 153440224 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 82fad51a..c1178f8d 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7968c2c1ec4e6264e91324f649f2bb44db04e53ce20f90f3a77c56abf2525664 -size 78184384 +oid sha256:5a20e07b5f659e1a9a4d32788cfd26ef1b0e49249af499dd431d5f559f02f621 +size 78230976 From 3383d042f3b389f0a85862b90c5092d0c5d003e3 Mon Sep 17 00:00:00 2001 From: cx-daniel-greenspan <33864348+cx-daniel-greenspan@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:10:31 +0000 Subject: [PATCH 02/42] Update checkmarx-ast-cli to 2.3.29 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index f7fb770b..1e71de98 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.28 +2.3.29 From ba44a5e5c6a6de121bc8895a1c19e7538bb089b8 Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Fri, 8 Aug 2025 11:08:57 +0530 Subject: [PATCH 03/42] Create main.yml --- .github/workflows/main.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..97546479 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,33 @@ +name: ReleaseCreation + +on: + workflow_dispatch: + +jobs: + say-hello: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Say Hello + run: echo "Hello, World!" + + - name: Get Current Date + id: current-date + run: echo "date=$(date +%Y-%m-%d)" >> $GITHUB_ENV + + - name: Create New JIRA Release + uses: satak/webrequest-action@master + with: + url: ${{ secrets.JIRA_RELEASE_WEBHOOK_URL }} + headers: '{"X-Automation-Webhook-Token": "${{ secrets.JIRA_RELEASE_WEBHOOK_TOKEN }}"}' + method: POST + payload: | + { + "data": { + "version": "testjavaversion#", + "startDate": "${{ env.date }}", + "date": "${{ env.date }}" + } + } From 992f9217343bd868545b1e42cacffb99c33bd74d Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Fri, 8 Aug 2025 12:38:27 +0530 Subject: [PATCH 04/42] Other/jira release test ( AST-0000) (#433) * test jira release creation * Deleted unused GH Action * updated team name --- .github/workflows/pr-automation.yml | 22 ---------------------- .github/workflows/release.yml | 2 +- 2 files changed, 1 insertion(+), 23 deletions(-) delete mode 100644 .github/workflows/pr-automation.yml diff --git a/.github/workflows/pr-automation.yml b/.github/workflows/pr-automation.yml deleted file mode 100644 index 2c5da62c..00000000 --- a/.github/workflows/pr-automation.yml +++ /dev/null @@ -1,22 +0,0 @@ -# name: PR Automation -# on: -# pull_request_target: -# types: [ready_for_review, opened, reopened] - -# permissions: -# contents: none -# issues: write -# pull-requests: write - -# jobs: -# add-reviewers: -# runs-on: ubuntu-latest -# if: ${{ github.event.pull_request.user.type != 'Bot' }} -# steps: -# - name: Request reviewers -# env: -# GH_REPO: ${{ github.repository }} -# GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} -# PRNUM: ${{ github.event.pull_request.number }} -# PRAUTHOR: ${{ github.event.pull_request.user.login }} -# run: gh pr edit $PRNUM diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 27426c7b..f37c9164 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -139,7 +139,7 @@ jobs: product_name: Java Wrapper release_version: ${{ needs.release.outputs.TAG_NAME }} cli_release_version: ${{ needs.release.outputs.CLI_VERSION }} - release_author: "Phoenix Team" + release_author: "Sypher Team" release_url: https://github.com/CheckmarxDev/ast-cli-java-wrapper/releases/tag/${{ needs.release.outputs.TAG_NAME }} jira_product_name: JAVA_WRAPPER secrets: inherit From e1c3f3d2ab59a4c91419df40b10a14f21535a4b0 Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Fri, 8 Aug 2025 14:27:58 +0530 Subject: [PATCH 05/42] Update main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 97546479..7ebad9d3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -name: ReleaseCreation +name: TEST_ReleaseCreation on: workflow_dispatch: From 131e3518a46d849e4d40fbe7f3473f9dcb6b9b05 Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Fri, 8 Aug 2025 14:39:39 +0530 Subject: [PATCH 06/42] Update main.yml --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7ebad9d3..1236c881 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,6 @@ jobs: uses: satak/webrequest-action@master with: url: ${{ secrets.JIRA_RELEASE_WEBHOOK_URL }} - headers: '{"X-Automation-Webhook-Token": "${{ secrets.JIRA_RELEASE_WEBHOOK_TOKEN }}"}' method: POST payload: | { From 75e5999bf1884e06cc09adfc6020bf85fb310c37 Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Fri, 8 Aug 2025 14:45:50 +0530 Subject: [PATCH 07/42] removing test file --- .github/workflows/main.yml | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 1236c881..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: TEST_ReleaseCreation - -on: - workflow_dispatch: - -jobs: - say-hello: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Say Hello - run: echo "Hello, World!" - - - name: Get Current Date - id: current-date - run: echo "date=$(date +%Y-%m-%d)" >> $GITHUB_ENV - - - name: Create New JIRA Release - uses: satak/webrequest-action@master - with: - url: ${{ secrets.JIRA_RELEASE_WEBHOOK_URL }} - method: POST - payload: | - { - "data": { - "version": "testjavaversion#", - "startDate": "${{ env.date }}", - "date": "${{ env.date }}" - } - } From 18527c6e76e2dfe72094f89a75b23deae272fb33 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 12 Aug 2025 08:35:01 +0000 Subject: [PATCH 08/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index d95a9412..a9c81874 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4ca697ea3e79160e94e885228c418d89e0a4eef9acae7c54f30ddab222c24d1 -size 76255416 +oid sha256:c5f1d1530c4b014c88f71bacd39056b7a7ab81e0182ab5c5d53510ae23fbee6b +size 76267704 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index ef897526..4f318b2f 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9d748161f3fc39b71dcf33a69cf4143134359427eed7756c1d49bf262571cf1 +oid sha256:87d412c6aae2219aa6c7fa7b7e1be82244e09b518945f0cb7cdb320cc367533f size 72745144 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index db1af770..614d9a31 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cd662a538ae11c59010aef4e0fdea48e10f838aad5e3b75fc08112c089a4bbfe -size 153440224 +oid sha256:1dcf2f936579b14ff720c9c8a2f1e20bfbbafba5c55a0ddbcfdf7da33d8d8a4e +size 153473376 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index c1178f8d..b73bea35 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5a20e07b5f659e1a9a4d32788cfd26ef1b0e49249af499dd431d5f559f02f621 -size 78230976 +oid sha256:d73427614ba9f0ee82aa0799f3eacee0e156add164690a9a1276464743227572 +size 78246336 From 99452c555b4d91da97dab9903d64067c283fcdd6 Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Tue, 12 Aug 2025 08:35:01 +0000 Subject: [PATCH 09/42] Update checkmarx-ast-cli to 2.3.30 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index 1e71de98..ad0b729f 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.29 +2.3.30 From 0ffe1a35816d02ece86e12ed4e784213345a5499 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 18 Aug 2025 11:06:33 +0000 Subject: [PATCH 10/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 4 ++-- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index a9c81874..f13ea12f 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c5f1d1530c4b014c88f71bacd39056b7a7ab81e0182ab5c5d53510ae23fbee6b -size 76267704 +oid sha256:e3c50ad34756b7a518f5aa1acc041e6f70c4cf76b43b757361bc4eba10df7581 +size 76648632 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index 4f318b2f..b3c5e02d 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:87d412c6aae2219aa6c7fa7b7e1be82244e09b518945f0cb7cdb320cc367533f -size 72745144 +oid sha256:0de6e35538f9b4f0a5f95b25dcca00fe1545bd7832c90c8b3f75cc81b4fa58d8 +size 73072824 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 614d9a31..f4d5e343 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1dcf2f936579b14ff720c9c8a2f1e20bfbbafba5c55a0ddbcfdf7da33d8d8a4e -size 153473376 +oid sha256:61abb3dbc8dbaaf4f5511a635b10856eb950b0293a960237e7fcd8d0a46ccd60 +size 154228992 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index b73bea35..90c23f28 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d73427614ba9f0ee82aa0799f3eacee0e156add164690a9a1276464743227572 -size 78246336 +oid sha256:5f447646a15fa72bd6dec0764fa357cb1058f4412935653c402fb739482e6ca0 +size 78635968 From 407a3488657b85de77c1498750567adba2acedaf Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Mon, 18 Aug 2025 11:06:34 +0000 Subject: [PATCH 11/42] Update checkmarx-ast-cli to 2.3.31 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index ad0b729f..dbe139d4 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.30 +2.3.31 From 320dfe3067d8e391dc72cb3b77a5d658717a8fee Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 21 Aug 2025 10:33:14 +0000 Subject: [PATCH 12/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 2 +- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index f13ea12f..50792ef5 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3c50ad34756b7a518f5aa1acc041e6f70c4cf76b43b757361bc4eba10df7581 +oid sha256:d516e996f4971e7516dc91f0676c588b897a792ab85a532d6b6bf41a9bd084ae size 76648632 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index b3c5e02d..c7fd41aa 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0de6e35538f9b4f0a5f95b25dcca00fe1545bd7832c90c8b3f75cc81b4fa58d8 +oid sha256:a7671f025f256a94ec67e9805a1fb1f71ccf08f4c27a90dc156ca9a5556201aa size 73072824 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index f4d5e343..1d478e93 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61abb3dbc8dbaaf4f5511a635b10856eb950b0293a960237e7fcd8d0a46ccd60 -size 154228992 +oid sha256:954940965bb8769fd0440ce0b5a520cd5863ab3035c8953755ff071e8bc28f47 +size 154241504 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 90c23f28..7590ba6d 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f447646a15fa72bd6dec0764fa357cb1058f4412935653c402fb739482e6ca0 -size 78635968 +oid sha256:8d56b322af737d1627b6ab557d060763be537bc140071e20019354ad59b7e22d +size 78636992 From 289aa805820daf7a8d693edc2176550f313a58c8 Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Thu, 21 Aug 2025 10:33:15 +0000 Subject: [PATCH 13/42] Update checkmarx-ast-cli to 2.3.32 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index dbe139d4..a17d933d 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.31 +2.3.32 From 953c468116e487f77087e492c8b3c368e4c16177 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 29 Aug 2025 07:04:02 +0000 Subject: [PATCH 14/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 4 ++-- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 50792ef5..6a190ceb 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d516e996f4971e7516dc91f0676c588b897a792ab85a532d6b6bf41a9bd084ae -size 76648632 +oid sha256:bd90806fae564acc02fc8aaa654168d3f7cece9fa64fddfa4db41300032bca8d +size 80113848 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index c7fd41aa..0695350a 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7671f025f256a94ec67e9805a1fb1f71ccf08f4c27a90dc156ca9a5556201aa -size 73072824 +oid sha256:0034ef1a37ed4a903edab70926416fb5fe68e2f3f0db51b7f76a5461745edfda +size 76480696 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 1d478e93..27db40b1 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:954940965bb8769fd0440ce0b5a520cd5863ab3035c8953755ff071e8bc28f47 -size 154241504 +oid sha256:c078e157df7c0afb379a37570c1b1b00fdde502985b400ababd9de8e116400e1 +size 161259440 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 7590ba6d..2e370a56 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d56b322af737d1627b6ab557d060763be537bc140071e20019354ad59b7e22d -size 78636992 +oid sha256:231b3cde441c40800b59876ff3efaade94fb607bc7d920c2a96a8306eaf1b5d2 +size 82096064 From 84eb753b263ef4aa89b2208685b8757aabf7680c Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Fri, 29 Aug 2025 07:04:02 +0000 Subject: [PATCH 15/42] Update checkmarx-ast-cli to 2.3.33 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index a17d933d..6ebf9fbf 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.32 +2.3.33 From 3c1464a10e8d1b948d4008b05c1b5405732a459d Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 12 Sep 2025 14:03:52 +0000 Subject: [PATCH 16/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 6a190ceb..1830bfe4 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd90806fae564acc02fc8aaa654168d3f7cece9fa64fddfa4db41300032bca8d -size 80113848 +oid sha256:dec9d95acacc254442ed3348d7284829fbdc34a818466f719649c74991c308ad +size 80122040 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index 0695350a..756d3efb 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0034ef1a37ed4a903edab70926416fb5fe68e2f3f0db51b7f76a5461745edfda +oid sha256:597b8ddef8d3d12e8e57f5af37b40ea453b7e1b6bd4a045848b5583e74366731 size 76480696 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 27db40b1..99d2115c 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c078e157df7c0afb379a37570c1b1b00fdde502985b400ababd9de8e116400e1 -size 161259440 +oid sha256:8528a90c0ee56e09c2aeb82f75ae4f5b06ecb7094a17991fb0ef41c1a3fa0cdb +size 161276112 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 2e370a56..9e1310a1 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:231b3cde441c40800b59876ff3efaade94fb607bc7d920c2a96a8306eaf1b5d2 -size 82096064 +oid sha256:4c07f01a2e147d22656fd7e3e53d9fc3f59a24283635915513c932e4a3e5c519 +size 82099648 From 6fb0681c8114b5d1893ef3b11b5bb8a08eaf12d8 Mon Sep 17 00:00:00 2001 From: cx-anjali-deore <200181980+cx-anjali-deore@users.noreply.github.com> Date: Fri, 12 Sep 2025 14:03:52 +0000 Subject: [PATCH 17/42] Update checkmarx-ast-cli to 2.3.34 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index 6ebf9fbf..0f74d3b3 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.33 +2.3.34 From 717e7fcf79cb0d8e1a062ba37b12a2703f6a382e Mon Sep 17 00:00:00 2001 From: Atish Jadhav <141334503+cx-atish-jadhav@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:11:48 +0530 Subject: [PATCH 18/42] Activate SCS engine support for JetBrains plugin (#440) * Activate SCS engine support for JetBrains plugin --- .../java/com/checkmarx/ast/results/result/Data.java | 12 +++++++++++- .../com/checkmarx/ast/results/result/Result.java | 13 ++++++++++++- .../java/com/checkmarx/ast/wrapper/CxConstants.java | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/checkmarx/ast/results/result/Data.java b/src/main/java/com/checkmarx/ast/results/result/Data.java index e9427663..35bda141 100644 --- a/src/main/java/com/checkmarx/ast/results/result/Data.java +++ b/src/main/java/com/checkmarx/ast/results/result/Data.java @@ -31,6 +31,10 @@ public class Data { List nodes; List packageData; ScaPackageData scaPackageData; + // Secret Detection specific fields + String ruleName; + String ruleDescription; + String remediation; public Data(@JsonProperty("queryId") String queryId, @JsonProperty("queryName") String queryName, @@ -47,7 +51,10 @@ public Data(@JsonProperty("queryId") String queryId, @JsonProperty("line") int line, @JsonProperty("nodes") List nodes, @JsonProperty("packageData") List packageData, - @JsonProperty("scaPackageData") ScaPackageData scaPackageData) { + @JsonProperty("scaPackageData") ScaPackageData scaPackageData, + @JsonProperty("ruleName") String ruleName, + @JsonProperty("ruleDescription") String ruleDescription, + @JsonProperty("remediation") String remediation) { this.queryId = queryId; this.queryName = queryName; this.group = group; @@ -64,5 +71,8 @@ public Data(@JsonProperty("queryId") String queryId, this.nodes = nodes; this.packageData = packageData; this.scaPackageData = scaPackageData; + this.ruleName = ruleName; + this.ruleDescription = ruleDescription; + this.remediation = remediation; } } diff --git a/src/main/java/com/checkmarx/ast/results/result/Result.java b/src/main/java/com/checkmarx/ast/results/result/Result.java index 19686ab2..7217af2b 100644 --- a/src/main/java/com/checkmarx/ast/results/result/Result.java +++ b/src/main/java/com/checkmarx/ast/results/result/Result.java @@ -1,5 +1,6 @@ package com.checkmarx.ast.results.result; +import com.checkmarx.ast.wrapper.CxConstants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -53,7 +54,7 @@ public Result(@JsonProperty("type") String type, @JsonProperty("comments") Comments comments, @JsonProperty("vulnerabilityDetails") VulnerabilityDetails vulnerabilityDetails, @JsonProperty("scaType") String scaType) { - this.type = type; + this.type = normalizeType(type); this.scaType=scaType; this.label = label; this.id = id; @@ -74,4 +75,14 @@ public Result(@JsonProperty("type") String type, this.comments = comments; this.vulnerabilityDetails = vulnerabilityDetails; } + + /** + * Normalizes special-case types coming from JSON into internal constants. + */ + private static String normalizeType(String rawType) { + if ("sscs-secret-detection".equals(rawType)) { + return CxConstants.SECRET_DETECTION; + } + return rawType; // leave other engine types unchanged + } } diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java index 889bbb65..5f1b8f62 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java @@ -13,6 +13,7 @@ public final class CxConstants { public static final String AGENT = "--agent"; public static final String SAST = "sast"; public static final String DEBUG = "--debug"; + public static final String SECRET_DETECTION = "scs"; static final String CLIENT_ID = "--client-id"; static final String CLIENT_SECRET = "--client-secret"; static final String API_KEY = "--apikey"; From a87df200d3646afbcb666d16667d8ef6c7dcb1c9 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 15 Sep 2025 10:42:35 +0000 Subject: [PATCH 19/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 2 +- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 1830bfe4..5dff3bf0 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dec9d95acacc254442ed3348d7284829fbdc34a818466f719649c74991c308ad +oid sha256:8613abbbd4a1a5b16dece3bfdca268f0ef54bea47d779c0fc7b6f2d590bb7bb6 size 80122040 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index 756d3efb..37064ea9 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:597b8ddef8d3d12e8e57f5af37b40ea453b7e1b6bd4a045848b5583e74366731 +oid sha256:5a40a9545d51d4d60943d81ed8f7031f99c4e3cfc0940a3b083fd4d068ea7cad size 76480696 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 99d2115c..b2787ac8 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8528a90c0ee56e09c2aeb82f75ae4f5b06ecb7094a17991fb0ef41c1a3fa0cdb -size 161276112 +oid sha256:81b18ae0206cf44631c6e28a4c08c12c4f198dd2dd4c74635a7d2c8e617117b0 +size 161276144 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 9e1310a1..bdaa5513 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c07f01a2e147d22656fd7e3e53d9fc3f59a24283635915513c932e4a3e5c519 -size 82099648 +oid sha256:6250391706fb243d66bba9b5d565f94032b23b681832bcc9b9512d59c7eca71b +size 82100160 From df8dede62e24850b701ecb287af17bb9aae986cf Mon Sep 17 00:00:00 2001 From: cx-anjali-deore <200181980+cx-anjali-deore@users.noreply.github.com> Date: Mon, 15 Sep 2025 10:42:36 +0000 Subject: [PATCH 20/42] Update checkmarx-ast-cli to 2.3.35 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index 0f74d3b3..c4eba4b3 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.34 +2.3.35 From 293531c0ab752885084df28d10da434f9a9cd714 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 29 Sep 2025 10:22:19 +0000 Subject: [PATCH 21/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 5dff3bf0..3f6d174b 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8613abbbd4a1a5b16dece3bfdca268f0ef54bea47d779c0fc7b6f2d590bb7bb6 -size 80122040 +oid sha256:059e958eb6e2704f9e9ba7a51dd7efc086a85e53248000270d648944d5d6dae3 +size 80134328 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index 37064ea9..f1407c3d 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5a40a9545d51d4d60943d81ed8f7031f99c4e3cfc0940a3b083fd4d068ea7cad +oid sha256:75fe395dc699e20e599db8ee0d86a60b3dec3183ccfccfd5e7fbabfeda413cb0 size 76480696 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index b2787ac8..095113de 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:81b18ae0206cf44631c6e28a4c08c12c4f198dd2dd4c74635a7d2c8e617117b0 -size 161276144 +oid sha256:5fce2cbfd8eeca6831fc270a7798e978bf3123b17244492ab1b183a9ad224392 +size 161292816 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index bdaa5513..6e1a7980 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6250391706fb243d66bba9b5d565f94032b23b681832bcc9b9512d59c7eca71b -size 82100160 +oid sha256:25369c32dab311dd3554791e60deb6a5a40812be226477476599f9bfee1afcd9 +size 82113472 From 20eb111e59efb21f501d37f4e5a7d6e8e239c530 Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Mon, 29 Sep 2025 10:22:19 +0000 Subject: [PATCH 22/42] Update checkmarx-ast-cli to 2.3.36 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index c4eba4b3..f1e5f744 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.35 +2.3.36 From db5086ce80c83b2ec0c00b2b000369382ea557e4 Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Mon, 29 Sep 2025 15:55:25 +0530 Subject: [PATCH 23/42] Update CODEOWNERS --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index bb970776..7ba25c48 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -2,4 +2,4 @@ # Each line is a file pattern followed by one or more owners # Specify the default owners for the entire repository -* @cx-anurag-dalke @cx-anand-nandeshwar @cx-atish-jadhav +#* @cx-anurag-dalke @cx-anand-nandeshwar @cx-atish-jadhav From 3026cdcfa96351e03aad6e6b98d195f95ede72f0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 14 Oct 2025 12:31:47 +0000 Subject: [PATCH 24/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 4 ++-- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 3f6d174b..b2bf1083 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:059e958eb6e2704f9e9ba7a51dd7efc086a85e53248000270d648944d5d6dae3 -size 80134328 +oid sha256:d8a163b3d50dc671973659d554b9032ee19f997f7a487471de0e594ed5039c8f +size 80904376 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index f1407c3d..56a6578c 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75fe395dc699e20e599db8ee0d86a60b3dec3183ccfccfd5e7fbabfeda413cb0 -size 76480696 +oid sha256:b36e1b5f28d064b89a312f1b62ec14431fc241a64382f11f7da0d9a88f7958ac +size 77201592 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 095113de..f5a32f12 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5fce2cbfd8eeca6831fc270a7798e978bf3123b17244492ab1b183a9ad224392 -size 161292816 +oid sha256:243204210f2f9701cfac5878ba3bd13f1950fbc2cb2caec3b816155cc8269daf +size 162805056 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 6e1a7980..a2f87460 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:25369c32dab311dd3554791e60deb6a5a40812be226477476599f9bfee1afcd9 -size 82113472 +oid sha256:28d5ebfcb41c7e6705c89407ffefec5de2c08c14c1b0c8a9e1121f11eb15c77c +size 82922432 From 28316102cee9acf6d7d79f9b8bef27c03a92d407 Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Tue, 14 Oct 2025 12:31:47 +0000 Subject: [PATCH 25/42] Update checkmarx-ast-cli to 2.3.37 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index f1e5f744..af6c3247 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.36 +2.3.37 From 5103021e81b1f1e4bd2ebb0d97134b5e9c6065c6 Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Thu, 6 Nov 2025 07:41:27 +0530 Subject: [PATCH 26/42] Update checkmarx-ast-cli binaries with 2.3.39 (#445) * Track Checkmarx CLI binaries with Git LFS * Update checkmarx-ast-cli to 2.3.39 --------- Co-authored-by: github-actions --- checkmarx-ast-cli.version | 2 +- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index af6c3247..4a8b8152 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.37 +2.3.39 diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index b2bf1083..86135309 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8a163b3d50dc671973659d554b9032ee19f997f7a487471de0e594ed5039c8f -size 80904376 +oid sha256:c1691b90d278d9306df4b6d9ba53b8feefd4f6e8d1193694ed6963ed10a1b902 +size 80908472 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index 56a6578c..f325e0d6 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b36e1b5f28d064b89a312f1b62ec14431fc241a64382f11f7da0d9a88f7958ac +oid sha256:e600b0f7f8e3590480010c08ec68be4a1413a9f8e79c9011a6219a98076686df size 77201592 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index f5a32f12..3c13c920 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:243204210f2f9701cfac5878ba3bd13f1950fbc2cb2caec3b816155cc8269daf -size 162805056 +oid sha256:69fc81fa9364d5f062520d3f356b775ad22fe1b1103fb6dded52d5843e8f84c4 +size 162805296 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index a2f87460..7f2ab887 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28d5ebfcb41c7e6705c89407ffefec5de2c08c14c1b0c8a9e1121f11eb15c77c -size 82922432 +oid sha256:be3ecf08a5eb0d74052b5de7abee3171628668c48544cb15d461e5549b175d5c +size 82926016 From 317a09ed5fb1fb83aa3c35c0136ba2748443f323 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 20 Nov 2025 10:40:48 +0000 Subject: [PATCH 27/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 4 ++-- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 86135309..ab37b459 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1691b90d278d9306df4b6d9ba53b8feefd4f6e8d1193694ed6963ed10a1b902 -size 80908472 +oid sha256:64460df9a00bcc48a599688c878ddabe20187127f5f7e0fb84cee08abc21120f +size 80982200 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index f325e0d6..dbedcd93 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e600b0f7f8e3590480010c08ec68be4a1413a9f8e79c9011a6219a98076686df -size 77201592 +oid sha256:823ba8fb7a41df2198af4371c1868d06e8ec1116cc8c98a1a6ba2e1502fa6090 +size 77267128 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 3c13c920..b4b2df59 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69fc81fa9364d5f062520d3f356b775ad22fe1b1103fb6dded52d5843e8f84c4 -size 162805296 +oid sha256:ab046570766900b90ca6412175eb60096bbbc1b251142237f4f836f54afb56be +size 162864288 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 7f2ab887..a62fc095 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be3ecf08a5eb0d74052b5de7abee3171628668c48544cb15d461e5549b175d5c -size 82926016 +oid sha256:606e331a9a722cf2668e6f8e09966f0972e483c3a2a1135277172194604b8195 +size 82958272 From f6ffd26ff51ee4c151f4e324f9dae9d4c665e050 Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:40:49 +0000 Subject: [PATCH 28/42] Update checkmarx-ast-cli to 2.3.40 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index 4a8b8152..0f1c3e55 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.39 +2.3.40 From e78d85200394f39e8e5ee8ccb3129aa0c467c0f7 Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Mon, 1 Dec 2025 17:02:02 +0530 Subject: [PATCH 29/42] Update release.yml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f37c9164..18845e81 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -140,7 +140,7 @@ jobs: release_version: ${{ needs.release.outputs.TAG_NAME }} cli_release_version: ${{ needs.release.outputs.CLI_VERSION }} release_author: "Sypher Team" - release_url: https://github.com/CheckmarxDev/ast-cli-java-wrapper/releases/tag/${{ needs.release.outputs.TAG_NAME }} + release_url: https://github.com/Checkmarx/ast-cli-java-wrapper/releases/tag/${{ needs.release.outputs.TAG_NAME }} jira_product_name: JAVA_WRAPPER secrets: inherit From 09bebed8ab2314f483725200a7434379332d3dba Mon Sep 17 00:00:00 2001 From: Atish Jadhav <141334503+cx-atish-jadhav@users.noreply.github.com> Date: Mon, 15 Dec 2025 13:26:35 +0530 Subject: [PATCH 30/42] Devassist: Realtime scanners (OSS, Secrets, Containers, IaC) with unified wrapper and enhanced parsing(AST-115438) (#451) * aimcp server changes * oss-realtime scanner changes * Create OssRealtimeVulnerability.java * Unify realtime scan wrappers; consolidate Secrets/IaC models; deprecate and stub obsolete result classes * Add ContainersRealtimeVulnerability model for containers realtime scan parsing * Add @JsonCreator constructor to OssRealtimeVulnerability for reliable Jackson deserialization * Refactoring package name and adding test for oss and mcp flag * Add integration tests for OSS, Container, and Secrets realtime scanners * Changed variable from id to CVE as per OSS response * Add maskedResult for secret remediation and change log level from INFO to DEBUG * Remove masked secrets functionality from codebase * Implemented mask cmd in java wrapper --------- Co-authored-by: cx-anand-nandeshwar <73646287+cx-anand-nandeshwar@users.noreply.github.com> --- .../ContainersRealtimeImage.java | 40 +++ .../ContainersRealtimeResults.java | 53 ++++ .../ContainersRealtimeVulnerability.java | 24 ++ .../ast/iacrealtime/IacRealtimeResults.java | 98 ++++++ .../com/checkmarx/ast/mask/MaskResult.java | 37 +++ .../com/checkmarx/ast/mask/MaskedSecret.java | 32 ++ .../ast/ossrealtime/OssRealtimeResults.java | 55 ++++ .../ossrealtime/OssRealtimeScanPackage.java | 44 +++ .../ossrealtime/OssRealtimeVulnerability.java | 31 ++ .../ast/realtime/RealtimeLocation.java | 28 ++ .../SecretsRealtimeResults.java | 94 ++++++ .../checkmarx/ast/wrapper/CxConstants.java | 8 + .../com/checkmarx/ast/wrapper/CxWrapper.java | 78 ++++- .../com/checkmarx/ast/wrapper/Execution.java | 4 +- .../ast/ContainersRealtimeResultsTest.java | 241 ++++++++++++++ .../checkmarx/ast/IacRealtimeResultsTest.java | 60 ++++ src/test/java/com/checkmarx/ast/MaskTest.java | 105 +++++++ .../checkmarx/ast/OssRealtimeParsingTest.java | 157 ++++++++++ src/test/java/com/checkmarx/ast/ScanTest.java | 15 + .../ast/SecretsRealtimeResultsTest.java | 293 ++++++++++++++++++ .../java/com/checkmarx/ast/TenantTest.java | 8 +- src/test/resources/Secrets-realtime.json | 147 +++++++++ src/test/resources/ignored-packages.json | 5 + 23 files changed, 1650 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeImage.java create mode 100644 src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeResults.java create mode 100644 src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeVulnerability.java create mode 100644 src/main/java/com/checkmarx/ast/iacrealtime/IacRealtimeResults.java create mode 100644 src/main/java/com/checkmarx/ast/mask/MaskResult.java create mode 100644 src/main/java/com/checkmarx/ast/mask/MaskedSecret.java create mode 100644 src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeResults.java create mode 100644 src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeScanPackage.java create mode 100644 src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeVulnerability.java create mode 100644 src/main/java/com/checkmarx/ast/realtime/RealtimeLocation.java create mode 100644 src/main/java/com/checkmarx/ast/secretsrealtime/SecretsRealtimeResults.java create mode 100644 src/test/java/com/checkmarx/ast/ContainersRealtimeResultsTest.java create mode 100644 src/test/java/com/checkmarx/ast/IacRealtimeResultsTest.java create mode 100644 src/test/java/com/checkmarx/ast/MaskTest.java create mode 100644 src/test/java/com/checkmarx/ast/OssRealtimeParsingTest.java create mode 100644 src/test/java/com/checkmarx/ast/SecretsRealtimeResultsTest.java create mode 100644 src/test/resources/Secrets-realtime.json create mode 100644 src/test/resources/ignored-packages.json diff --git a/src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeImage.java b/src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeImage.java new file mode 100644 index 00000000..7a6a33a6 --- /dev/null +++ b/src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeImage.java @@ -0,0 +1,40 @@ +package com.checkmarx.ast.containersrealtime; + +import com.checkmarx.ast.realtime.RealtimeLocation; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Value; + +import java.util.Collections; +import java.util.List; + +@Value +@JsonDeserialize +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContainersRealtimeImage { + @JsonProperty("ImageName") String imageName; + @JsonProperty("ImageTag") String imageTag; + @JsonProperty("FilePath") String filePath; + @JsonProperty("Locations") List locations; + @JsonProperty("Status") String status; + @JsonProperty("Vulnerabilities") List vulnerabilities; + + @JsonCreator + public ContainersRealtimeImage(@JsonProperty("ImageName") String imageName, + @JsonProperty("ImageTag") String imageTag, + @JsonProperty("FilePath") String filePath, + @JsonProperty("Locations") List locations, + @JsonProperty("Status") String status, + @JsonProperty("Vulnerabilities") List vulnerabilities) { + this.imageName = imageName; + this.imageTag = imageTag; + this.filePath = filePath; + this.locations = locations == null ? Collections.emptyList() : locations; + this.status = status; + this.vulnerabilities = vulnerabilities == null ? Collections.emptyList() : vulnerabilities; + } +} \ No newline at end of file diff --git a/src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeResults.java b/src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeResults.java new file mode 100644 index 00000000..f9054ffe --- /dev/null +++ b/src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeResults.java @@ -0,0 +1,53 @@ +package com.checkmarx.ast.containersrealtime; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Value; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.List; + +@Value +@JsonDeserialize +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContainersRealtimeResults { + private static final Logger log = LoggerFactory.getLogger(ContainersRealtimeResults.class); + + @JsonProperty("Images") List images; + + @JsonCreator + public ContainersRealtimeResults(@JsonProperty("Images") List images) { + this.images = images; + } + + public static ContainersRealtimeResults fromLine(String line) { + if (StringUtils.isBlank(line)) { + return null; + } + try { + if (line.contains("\"Images\"") && isValidJSON(line)) { + return new ObjectMapper().readValue(line, ContainersRealtimeResults.class); + } + } catch (IOException e) { + log.debug("Failed to parse containers realtime line: {}", line, e); + } + return null; + } + + private static boolean isValidJSON(String json) { + try { + new ObjectMapper().readTree(json); + return true; + } catch (IOException e) { + return false; + } + } +} diff --git a/src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeVulnerability.java b/src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeVulnerability.java new file mode 100644 index 00000000..cabe4b68 --- /dev/null +++ b/src/main/java/com/checkmarx/ast/containersrealtime/ContainersRealtimeVulnerability.java @@ -0,0 +1,24 @@ +package com.checkmarx.ast.containersrealtime; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Value; + +@Value +@JsonDeserialize +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContainersRealtimeVulnerability { + @JsonProperty("CVE") String cve; + @JsonProperty("Severity") String severity; + + @JsonCreator + public ContainersRealtimeVulnerability(@JsonProperty("CVE") String cve, + @JsonProperty("Severity") String severity) { + this.cve = cve; + this.severity = severity; + } +} \ No newline at end of file diff --git a/src/main/java/com/checkmarx/ast/iacrealtime/IacRealtimeResults.java b/src/main/java/com/checkmarx/ast/iacrealtime/IacRealtimeResults.java new file mode 100644 index 00000000..0afc103f --- /dev/null +++ b/src/main/java/com/checkmarx/ast/iacrealtime/IacRealtimeResults.java @@ -0,0 +1,98 @@ +package com.checkmarx.ast.iacrealtime; + +import com.checkmarx.ast.realtime.RealtimeLocation; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Value; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +@Value +@JsonDeserialize +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class IacRealtimeResults { + private static final Logger log = LoggerFactory.getLogger(IacRealtimeResults.class); + @JsonProperty("Results") List results; // Normalized list (array or single object) + + @JsonCreator + public IacRealtimeResults(@JsonProperty("Results") List results) { + this.results = results == null ? Collections.emptyList() : results; + } + + @Value + @JsonDeserialize + @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Issue { + @JsonProperty("Title") String title; + @JsonProperty("Description") String description; + @JsonProperty("SimilarityID") String similarityId; + @JsonProperty("FilePath") String filePath; + @JsonProperty("Severity") String severity; + @JsonProperty("ExpectedValue") String expectedValue; + @JsonProperty("ActualValue") String actualValue; + @JsonProperty("Locations") List locations; + + @JsonCreator + public Issue(@JsonProperty("Title") String title, + @JsonProperty("Description") String description, + @JsonProperty("SimilarityID") String similarityId, + @JsonProperty("FilePath") String filePath, + @JsonProperty("Severity") String severity, + @JsonProperty("ExpectedValue") String expectedValue, + @JsonProperty("ActualValue") String actualValue, + @JsonProperty("Locations") List locations) { + this.title = title; + this.description = description; + this.similarityId = similarityId; + this.filePath = filePath; + this.severity = severity; + this.expectedValue = expectedValue; + this.actualValue = actualValue; + this.locations = locations == null ? Collections.emptyList() : locations; + } + } + + public static IacRealtimeResults fromLine(String line) { + if (StringUtils.isBlank(line)) { + return null; + } + try { + if (!isValidJSON(line)) { + return null; + } + ObjectMapper mapper = new ObjectMapper(); + String trimmed = line.trim(); + if (trimmed.startsWith("[")) { + List list = mapper.readValue(trimmed, mapper.getTypeFactory().constructCollectionType(List.class, Issue.class)); + return new IacRealtimeResults(list == null ? Collections.emptyList() : list); + } + if (trimmed.startsWith("{")) { + Issue single = mapper.readValue(trimmed, Issue.class); + return new IacRealtimeResults(Collections.singletonList(single)); + } + } catch (IOException e) { + log.debug("Failed to parse iac realtime JSON line: {}", line, e); + } + return null; + } + + private static boolean isValidJSON(String json) { + try { + new ObjectMapper().readTree(json); + return true; + } catch (IOException e) { + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/checkmarx/ast/mask/MaskResult.java b/src/main/java/com/checkmarx/ast/mask/MaskResult.java new file mode 100644 index 00000000..80d9e8bb --- /dev/null +++ b/src/main/java/com/checkmarx/ast/mask/MaskResult.java @@ -0,0 +1,37 @@ +package com.checkmarx.ast.mask; + +import com.checkmarx.ast.utils.JsonParser; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.type.TypeFactory; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import lombok.Value; + +import java.util.List; + +@Value +@EqualsAndHashCode() +@JsonDeserialize() +@ToString(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class MaskResult { + + List maskedSecrets; + String maskedFile; + + @JsonCreator + public MaskResult(@JsonProperty("maskedSecrets") List maskedSecrets, + @JsonProperty("maskedFile") String maskedFile) { + this.maskedSecrets = maskedSecrets; + this.maskedFile = maskedFile; + } + + public static MaskResult fromLine(String line) { + return JsonParser.parse(line, TypeFactory.defaultInstance().constructType(MaskResult.class)); + } +} diff --git a/src/main/java/com/checkmarx/ast/mask/MaskedSecret.java b/src/main/java/com/checkmarx/ast/mask/MaskedSecret.java new file mode 100644 index 00000000..a18e8827 --- /dev/null +++ b/src/main/java/com/checkmarx/ast/mask/MaskedSecret.java @@ -0,0 +1,32 @@ +package com.checkmarx.ast.mask; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import lombok.Value; + +@Value +@EqualsAndHashCode() +@JsonDeserialize() +@ToString(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class MaskedSecret { + + String masked; + String secret; + int line; + + @JsonCreator + public MaskedSecret(@JsonProperty("masked") String masked, + @JsonProperty("secret") String secret, + @JsonProperty("line") int line) { + this.masked = masked; + this.secret = secret; + this.line = line; + } +} diff --git a/src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeResults.java b/src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeResults.java new file mode 100644 index 00000000..7141370f --- /dev/null +++ b/src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeResults.java @@ -0,0 +1,55 @@ +package com.checkmarx.ast.ossrealtime; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Value; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +@Value +@JsonDeserialize +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class OssRealtimeResults { + private static final Logger log = LoggerFactory.getLogger(OssRealtimeResults.class); + + @JsonProperty("Packages") List packages; + + @JsonCreator + public OssRealtimeResults(@JsonProperty("Packages") List packages) { + this.packages = packages == null ? Collections.emptyList() : packages; + } + + public static OssRealtimeResults fromLine(String line) { + if (StringUtils.isBlank(line)) { + return null; + } + try { + if (isValidJSON(line) && line.contains("\"Packages\"")) { + return new ObjectMapper().readValue(line, OssRealtimeResults.class); + } + } catch (IOException e) { + log.debug("Failed to parse oss realtime line: {}", line, e); + } + return null; + } + + private static boolean isValidJSON(String json) { + try { + new ObjectMapper().readTree(json); + return true; + } catch (IOException e) { + return false; + } + } +} + diff --git a/src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeScanPackage.java b/src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeScanPackage.java new file mode 100644 index 00000000..d4b32771 --- /dev/null +++ b/src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeScanPackage.java @@ -0,0 +1,44 @@ +package com.checkmarx.ast.ossrealtime; + +import com.checkmarx.ast.realtime.RealtimeLocation; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Value; + +import java.util.Collections; +import java.util.List; + +@Value +@JsonDeserialize +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class OssRealtimeScanPackage { + @JsonProperty("PackageManager") String packageManager; + @JsonProperty("PackageName") String packageName; + @JsonProperty("PackageVersion") String packageVersion; + @JsonProperty("FilePath") String filePath; + @JsonProperty("Locations") List locations; + @JsonProperty("Status") String status; + @JsonProperty("Vulnerabilities") List vulnerabilities; + + @JsonCreator + public OssRealtimeScanPackage(@JsonProperty("PackageManager") String packageManager, + @JsonProperty("PackageName") String packageName, + @JsonProperty("PackageVersion") String packageVersion, + @JsonProperty("FilePath") String filePath, + @JsonProperty("Locations") List locations, + @JsonProperty("Status") String status, + @JsonProperty("Vulnerabilities") List vulnerabilities) { + this.packageManager = packageManager; + this.packageName = packageName; + this.packageVersion = packageVersion; + this.filePath = filePath; + this.locations = locations == null ? Collections.emptyList() : locations; + this.status = status; + this.vulnerabilities = vulnerabilities == null ? Collections.emptyList() : vulnerabilities; + } +} + diff --git a/src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeVulnerability.java b/src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeVulnerability.java new file mode 100644 index 00000000..ac89b368 --- /dev/null +++ b/src/main/java/com/checkmarx/ast/ossrealtime/OssRealtimeVulnerability.java @@ -0,0 +1,31 @@ +package com.checkmarx.ast.ossrealtime; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Value; + +@Value +@JsonDeserialize +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class OssRealtimeVulnerability { + @JsonProperty("CVE") String cve; + @JsonProperty("Severity") String severity; + @JsonProperty("Description") String description; + @JsonProperty("FixVersion") String fixVersion; + + @JsonCreator + public OssRealtimeVulnerability(@JsonProperty("CVE") String cve, + @JsonProperty("Severity") String severity, + @JsonProperty("Description") String description, + @JsonProperty("FixVersion") String fixVersion) { + this.cve = cve; + this.severity = severity; + this.description = description; + this.fixVersion = fixVersion; + } +} + diff --git a/src/main/java/com/checkmarx/ast/realtime/RealtimeLocation.java b/src/main/java/com/checkmarx/ast/realtime/RealtimeLocation.java new file mode 100644 index 00000000..277fe13d --- /dev/null +++ b/src/main/java/com/checkmarx/ast/realtime/RealtimeLocation.java @@ -0,0 +1,28 @@ +package com.checkmarx.ast.realtime; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Value; + +@Value +@JsonDeserialize +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class RealtimeLocation { + @JsonProperty("Line") int line; + @JsonProperty("StartIndex") int startIndex; + @JsonProperty("EndIndex") int endIndex; + + @JsonCreator + public RealtimeLocation(@JsonProperty("Line") int line, + @JsonProperty("StartIndex") int startIndex, + @JsonProperty("EndIndex") int endIndex) { + this.line = line; + this.startIndex = startIndex; + this.endIndex = endIndex; + } +} + diff --git a/src/main/java/com/checkmarx/ast/secretsrealtime/SecretsRealtimeResults.java b/src/main/java/com/checkmarx/ast/secretsrealtime/SecretsRealtimeResults.java new file mode 100644 index 00000000..ef19050c --- /dev/null +++ b/src/main/java/com/checkmarx/ast/secretsrealtime/SecretsRealtimeResults.java @@ -0,0 +1,94 @@ +package com.checkmarx.ast.secretsrealtime; + +import com.checkmarx.ast.realtime.RealtimeLocation; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Value; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +@Value +@JsonDeserialize +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class SecretsRealtimeResults { + private static final Logger log = LoggerFactory.getLogger(SecretsRealtimeResults.class); + + @JsonProperty("Secrets") List secrets; + + @JsonCreator + public SecretsRealtimeResults(@JsonProperty("Secrets") List secrets) { + this.secrets = secrets == null ? Collections.emptyList() : secrets; + } + + @Value + @JsonDeserialize + @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Secret { + @JsonProperty("Title") String title; + @JsonProperty("Description") String description; + @JsonProperty("SecretValue") String secretValue; + @JsonProperty("FilePath") String filePath; + @JsonProperty("Severity") String severity; + @JsonProperty("Locations") List locations; + + @JsonCreator + public Secret(@JsonProperty("Title") String title, + @JsonProperty("Description") String description, + @JsonProperty("SecretValue") String secretValue, + @JsonProperty("FilePath") String filePath, + @JsonProperty("Severity") String severity, + @JsonProperty("Locations") List locations) { + this.title = title; + this.description = description; + this.secretValue = secretValue; + this.filePath = filePath; + this.severity = severity; + this.locations = locations == null ? Collections.emptyList() : locations; + } + } + + public static SecretsRealtimeResults fromLine(String line) { + if (StringUtils.isBlank(line)) { + return null; + } + try { + if (!isValidJSON(line)) { + return null; + } + ObjectMapper mapper = new ObjectMapper(); + String trimmed = line.trim(); + if (trimmed.startsWith("[")) { + List list = mapper.readValue(trimmed, mapper.getTypeFactory().constructCollectionType(List.class, Secret.class)); + return new SecretsRealtimeResults(list); + } + if (trimmed.startsWith("{")) { + Secret single = mapper.readValue(trimmed, Secret.class); + return new SecretsRealtimeResults(Collections.singletonList(single)); + } + } catch (IOException e) { + log.debug("Failed to parse secrets realtime JSON line: {}", line, e); + } + return null; + } + + private static boolean isValidJSON(String json) { + try { + new ObjectMapper().readTree(json); + return true; + } catch (IOException e) { + return false; + } + } +} + diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java index 5f1b8f62..dd8c6e69 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java @@ -74,4 +74,12 @@ public final class CxConstants { static final String SUB_CMD_LEARN_MORE = "learn-more"; static final String SUB_CMD_TENANT = "tenant"; static final String IDE_SCANS_KEY = "scan.config.plugins.ideScans"; + static final String AI_MCP_SERVER_KEY = "scan.config.plugins.aiMcpServer"; + static final String IGNORED_FILE_PATH = "--ignored-file-path"; + static final String SUB_CMD_OSS_REALTIME = "oss-realtime"; + static final String SUB_CMD_IAC_REALTIME = "iac-realtime"; + static final String SUB_CMD_SECRETS_REALTIME = "secrets-realtime"; + static final String SUB_CMD_CONTAINERS_REALTIME = "containers-realtime"; + static final String SUB_CMD_MASK = "mask"; + static final String RESULT_FILE = "--result-file"; } diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java index 38640d81..c49aa875 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java @@ -4,6 +4,12 @@ import com.checkmarx.ast.codebashing.CodeBashing; import com.checkmarx.ast.kicsRealtimeResults.KicsRealtimeResults; import com.checkmarx.ast.learnMore.LearnMore; +import com.checkmarx.ast.mask.MaskResult; +import com.checkmarx.ast.ossrealtime.OssRealtimeResults; +import com.checkmarx.ast.secretsrealtime.SecretsRealtimeResults; + +import com.checkmarx.ast.iacrealtime.IacRealtimeResults; +import com.checkmarx.ast.containersrealtime.ContainersRealtimeResults; import com.checkmarx.ast.predicate.CustomState; import com.checkmarx.ast.predicate.Predicate; import com.checkmarx.ast.project.Project; @@ -24,7 +30,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.lang.reflect.Field; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; @@ -396,7 +401,7 @@ public KicsRealtimeResults kicsRealtimeScan(@NonNull String fileSources, String arguments.add(fileSources); arguments.add(CxConstants.ADDITONAL_PARAMS); arguments.add(additionalParams); - if (engine.length() > 0) { + if (!engine.isEmpty()) { arguments.add(CxConstants.ENGINE); arguments.add(engine); } @@ -404,6 +409,48 @@ public KicsRealtimeResults kicsRealtimeScan(@NonNull String fileSources, String return Execution.executeCommand(withConfigArguments(arguments), logger, KicsRealtimeResults::fromLine); } + public T realtimeScan(@NonNull String subCommand, @NonNull String sourcePath, String ignoredFilePath, java.util.function.Function resultParser) + throws IOException, InterruptedException, CxException { + this.logger.info("Executing 'scan {}' command using the CLI.", subCommand); + this.logger.info("Source: {} IgnoredFilePath: {}", sourcePath, ignoredFilePath); + List arguments = new ArrayList<>(); + arguments.add(CxConstants.CMD_SCAN); + arguments.add(subCommand); + arguments.add(CxConstants.SOURCE); + arguments.add(sourcePath); + if (StringUtils.isNotBlank(ignoredFilePath)) { + arguments.add(CxConstants.IGNORED_FILE_PATH); + arguments.add(ignoredFilePath); + } + return Execution.executeCommand(withConfigArguments(arguments), logger, resultParser); + } + + // OSS Realtime + public OssRealtimeResults ossRealtimeScan(@NonNull String sourcePath, String ignoredFilePath) + throws IOException, InterruptedException, CxException { + return realtimeScan(CxConstants.SUB_CMD_OSS_REALTIME, sourcePath, ignoredFilePath, OssRealtimeResults::fromLine); + } + + // IAC Realtime + public IacRealtimeResults iacRealtimeScan(@NonNull String sourcePath, String ignoredFilePath) + throws IOException, InterruptedException, CxException { + return realtimeScan(CxConstants.SUB_CMD_IAC_REALTIME, sourcePath, ignoredFilePath, IacRealtimeResults::fromLine); + } + + // Secrets Realtime + public SecretsRealtimeResults secretsRealtimeScan(@NonNull String sourcePath, String ignoredFilePath) + throws IOException, InterruptedException, CxException { + return realtimeScan(CxConstants.SUB_CMD_SECRETS_REALTIME, sourcePath, ignoredFilePath, SecretsRealtimeResults::fromLine); + } + + + + // Containers Realtime + public ContainersRealtimeResults containersRealtimeScan(@NonNull String sourcePath, String ignoredFilePath) + throws IOException, InterruptedException, CxException { + return realtimeScan(CxConstants.SUB_CMD_CONTAINERS_REALTIME, sourcePath, ignoredFilePath, ContainersRealtimeResults::fromLine); + } + public KicsRemediation kicsRemediate(@NonNull String resultsFile, String kicsFile, String engine,String similarityIds) throws IOException, InterruptedException, CxException { this.logger.info("Executing 'remediation kics' command using the CLI."); @@ -418,11 +465,11 @@ public KicsRemediation kicsRemediate(@NonNull String resultsFile, String kicsFil arguments.add(resultsFile); arguments.add(CxConstants.KICS_REMEDIATION_KICS_FILE); arguments.add(kicsFile); - if (engine.length() > 0) { + if (!engine.isEmpty()) { arguments.add(CxConstants.ENGINE); arguments.add(engine); } - if (similarityIds.length() > 0) { + if (!similarityIds.isEmpty()) { arguments.add(CxConstants.KICS_REMEDIATION_SIMILARITY); arguments.add(similarityIds); } @@ -455,6 +502,18 @@ public boolean ideScansEnabled() throws CxException, IOException, InterruptedExc .orElse(false); } + public boolean aiMcpServerEnabled() throws CxException, IOException, InterruptedException { + List tenantSettings = tenantSettings(); + if (tenantSettings == null) { + throw new CxException(1, "Unable to parse tenant settings"); + } + return tenantSettings.stream() + .filter(t -> t.getKey().equals(CxConstants.AI_MCP_SERVER_KEY)) + .findFirst() + .map(t -> Boolean.parseBoolean(t.getValue())) + .orElse(false); + } + public List tenantSettings() throws CxException, IOException, InterruptedException { List arguments = jsonArguments(); @@ -464,6 +523,17 @@ public List tenantSettings() throws CxException, IOException, Int return Execution.executeCommand(withConfigArguments(arguments), logger, TenantSetting::listFromLine); } + public MaskResult maskSecrets(@NonNull String filePath) throws CxException, IOException, InterruptedException { + List arguments = new ArrayList<>(); + + arguments.add(CxConstants.CMD_UTILS); + arguments.add(CxConstants.SUB_CMD_MASK); + arguments.add(CxConstants.RESULT_FILE); + arguments.add(filePath); + + return Execution.executeCommand(withConfigArguments(arguments), logger, MaskResult::fromLine); + } + private int getIndexOfBfLNode(List bflNodes, List resultNodes) { int bflNodeNotFound = -1; diff --git a/src/main/java/com/checkmarx/ast/wrapper/Execution.java b/src/main/java/com/checkmarx/ast/wrapper/Execution.java index 9d45cac3..c233ff2d 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/Execution.java +++ b/src/main/java/com/checkmarx/ast/wrapper/Execution.java @@ -57,7 +57,7 @@ static T executeCommand(List arguments, String line; StringBuilder output = new StringBuilder(); while ((line = br.readLine()) != null) { - logger.info(line); + logger.debug(line); output.append(line).append(LINE_SEPARATOR); T parsedLine = lineParser.apply(line); if (parsedLine != null) { @@ -98,7 +98,7 @@ static String executeCommand(List arguments, String line; StringBuilder stringBuilder = new StringBuilder(); while ((line = br.readLine()) != null) { - logger.info(line); + logger.debug(line); stringBuilder.append(line).append(LINE_SEPARATOR); } process.waitFor(); diff --git a/src/test/java/com/checkmarx/ast/ContainersRealtimeResultsTest.java b/src/test/java/com/checkmarx/ast/ContainersRealtimeResultsTest.java new file mode 100644 index 00000000..6911e4af --- /dev/null +++ b/src/test/java/com/checkmarx/ast/ContainersRealtimeResultsTest.java @@ -0,0 +1,241 @@ +package com.checkmarx.ast; + +import com.checkmarx.ast.containersrealtime.ContainersRealtimeImage; +import com.checkmarx.ast.containersrealtime.ContainersRealtimeResults; +import com.checkmarx.ast.containersrealtime.ContainersRealtimeVulnerability; +import com.checkmarx.ast.wrapper.CxException; +import org.junit.jupiter.api.*; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Integration and unit tests for Container Realtime scanner functionality. + * Tests the complete workflow: CLI invocation -> JSON parsing -> domain object mapping. + * Integration tests use Dockerfile as the scan target and are assumption-guarded for CI/local flexibility. + */ +class ContainersRealtimeResultsTest extends BaseTest { + + private boolean isCliConfigured() { + return Optional.ofNullable(getConfig().getPathToExecutable()).filter(s -> !s.isEmpty()).isPresent(); + } + + /* ------------------------------------------------------ */ + /* Integration tests for Container Realtime scanning */ + /* ------------------------------------------------------ */ + + /** + * Tests basic container realtime scan functionality on Dockerfile. + * Verifies that the scan returns a valid results object with detected container images. + * This test validates the end-to-end workflow from CLI execution to domain object creation. + */ + @Test + @DisplayName("Basic container scan on Dockerfile returns detected images") + void basicContainerRealtimeScan() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String dockerfilePath = "src/test/resources/Dockerfile"; + Assumptions.assumeTrue(Files.exists(Paths.get(dockerfilePath)), "Dockerfile not found - cannot test container scanning"); + + ContainersRealtimeResults results = wrapper.containersRealtimeScan(dockerfilePath, ""); + + assertNotNull(results, "Scan should return non-null results"); + assertNotNull(results.getImages(), "Images list should be initialized"); + + // Verify that if images are detected, they have proper structure + if (!results.getImages().isEmpty()) { + results.getImages().forEach(image -> { + assertNotNull(image.getImageName(), "Image name should be populated"); + assertNotNull(image.getVulnerabilities(), "Vulnerabilities list should be initialized"); + }); + } + } + + /** + * Tests container scan with ignore file functionality. + * Verifies that providing an ignore file doesn't break the scanning process + * and produces consistent or reduced results compared to baseline scan. + */ + @Test + @DisplayName("Container scan with ignore file works correctly") + void containerRealtimeScanWithIgnoreFile() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String dockerfilePath = "src/test/resources/Dockerfile"; + String ignoreFile = "src/test/resources/ignored-packages.json"; + Assumptions.assumeTrue(Files.exists(Paths.get(dockerfilePath)) && Files.exists(Paths.get(ignoreFile)), + "Required test resources missing - cannot test ignore functionality"); + + ContainersRealtimeResults baseline = wrapper.containersRealtimeScan(dockerfilePath, ""); + ContainersRealtimeResults filtered = wrapper.containersRealtimeScan(dockerfilePath, ignoreFile); + + assertNotNull(baseline, "Baseline scan should return results"); + assertNotNull(filtered, "Filtered scan should return results"); + + // Ignore file should not increase the number of detected issues + if (baseline.getImages() != null && filtered.getImages() != null) { + assertTrue(filtered.getImages().size() <= baseline.getImages().size(), + "Filtered scan should not have more images than baseline"); + } + } + + /** + * Tests scan consistency by running the same container scan multiple times. + * Verifies that repeated scans of the same Dockerfile produce stable, deterministic results. + * This is important for CI/CD pipelines where consistent results are crucial. + */ + @Test + @DisplayName("Repeated container scans produce consistent results") + void containerRealtimeScanConsistency() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String dockerfilePath = "src/test/resources/Dockerfile"; + Assumptions.assumeTrue(Files.exists(Paths.get(dockerfilePath)), "Dockerfile not found - cannot test consistency"); + + ContainersRealtimeResults firstScan = wrapper.containersRealtimeScan(dockerfilePath, ""); + ContainersRealtimeResults secondScan = wrapper.containersRealtimeScan(dockerfilePath, ""); + + assertNotNull(firstScan, "First scan should return results"); + assertNotNull(secondScan, "Second scan should return results"); + + // Compare image counts for consistency + int firstImageCount = (firstScan.getImages() != null) ? firstScan.getImages().size() : 0; + int secondImageCount = (secondScan.getImages() != null) ? secondScan.getImages().size() : 0; + + assertEquals(firstImageCount, secondImageCount, + "Image count should be consistent across multiple scans"); + } + + /** + * Tests domain object mapping for container scan results. + * Verifies that JSON responses are properly parsed into domain objects + * and all expected fields are correctly mapped and initialized. + */ + @Test + @DisplayName("Container domain objects are properly mapped from scan results") + void containerDomainObjectMapping() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String dockerfilePath = "src/test/resources/Dockerfile"; + Assumptions.assumeTrue(Files.exists(Paths.get(dockerfilePath)), "Dockerfile not found - cannot test mapping"); + + ContainersRealtimeResults results = wrapper.containersRealtimeScan(dockerfilePath, ""); + assertNotNull(results, "Scan results should not be null"); + + // If images are detected, validate their structure + if (results.getImages() != null && !results.getImages().isEmpty()) { + ContainersRealtimeImage sampleImage = results.getImages().get(0); + + // Verify core image fields are mapped correctly + assertNotNull(sampleImage.getImageName(), "Image name should always be present"); + assertNotNull(sampleImage.getVulnerabilities(), "Vulnerabilities list should be initialized"); + + // If vulnerabilities exist, validate their structure + if (!sampleImage.getVulnerabilities().isEmpty()) { + ContainersRealtimeVulnerability sampleVuln = sampleImage.getVulnerabilities().get(0); + // CVE and Severity are the core fields that should be present + assertTrue(sampleVuln.getCve() != null || sampleVuln.getSeverity() != null, + "Vulnerability should have at least CVE or Severity information"); + } + } + } + + /** + * Tests error handling when scanning a non-existent file. + * Verifies that the scanner properly throws a CxException with meaningful error message + * when provided with invalid file paths, demonstrating proper error handling. + */ + @Test + @DisplayName("Container scan throws appropriate exception for non-existent file") + void containerScanHandlesInvalidPath() { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + + // Test with a non-existent file path + String invalidPath = "src/test/resources/NonExistentDockerfile"; + + // The CLI should throw a CxException with a meaningful error message for invalid paths + CxException exception = assertThrows(CxException.class, () -> + wrapper.containersRealtimeScan(invalidPath, "") + ); + + // Verify the exception contains information about the invalid file path + String errorMessage = exception.getMessage(); + assertNotNull(errorMessage, "Exception should contain an error message"); + assertTrue(errorMessage.contains("invalid file path") || errorMessage.contains("file") || errorMessage.contains("path"), + "Exception message should indicate the issue is related to file path: " + errorMessage); + } + + /* ------------------------------------------------------ */ + /* Unit tests for JSON parsing robustness */ + /* ------------------------------------------------------ */ + + /** + * Tests JSON parsing with valid container scan response. + * Verifies that well-formed JSON is correctly parsed into domain objects. + */ + @Test + @DisplayName("Valid JSON parsing creates correct domain objects") + void testFromLineWithValidJson() { + String json = "{" + + "\"Images\": [" + + " {" + + " \"ImageName\": \"nginx:latest\"," + + " \"Vulnerabilities\": [" + + " {" + + " \"CVE\": \"CVE-2021-2345\"," + + " \"Severity\": \"High\"" + + " }" + + " ]" + + " }" + + "]" + + "}"; + ContainersRealtimeResults results = ContainersRealtimeResults.fromLine(json); + assertNotNull(results); + assertEquals(1, results.getImages().size()); + ContainersRealtimeImage image = results.getImages().get(0); + assertEquals("nginx:latest", image.getImageName()); + assertEquals(1, image.getVulnerabilities().size()); + ContainersRealtimeVulnerability vulnerability = image.getVulnerabilities().get(0); + assertEquals("CVE-2021-2345", vulnerability.getCve()); + assertEquals("High", vulnerability.getSeverity()); + } + + /** + * Tests parsing robustness with malformed JSON. + * Verifies that the parser gracefully handles various edge cases. + */ + @Test + @DisplayName("Malformed JSON is handled gracefully") + void testFromLineWithEdgeCases() { + // Missing Images key + assertNull(ContainersRealtimeResults.fromLine("{\"some_other_key\": \"some_value\"}")); + + // Invalid JSON structure + assertNull(ContainersRealtimeResults.fromLine("{\"Images\": [}")); + + // Blank/null inputs + assertNull(ContainersRealtimeResults.fromLine("")); + assertNull(ContainersRealtimeResults.fromLine(" ")); + assertNull(ContainersRealtimeResults.fromLine(null)); + } + + /** + * Tests parsing with empty or null image arrays. + * Verifies that empty results are handled correctly. + */ + @Test + @DisplayName("Empty and null image arrays are handled correctly") + void testFromLineWithEmptyResults() { + // Empty images array + String emptyJson = "{\"Images\": []}"; + ContainersRealtimeResults emptyResults = ContainersRealtimeResults.fromLine(emptyJson); + assertNotNull(emptyResults); + assertTrue(emptyResults.getImages().isEmpty()); + + // Null images + String nullJson = "{\"Images\": null}"; + ContainersRealtimeResults nullResults = ContainersRealtimeResults.fromLine(nullJson); + assertNotNull(nullResults); + assertNull(nullResults.getImages()); + } +} + diff --git a/src/test/java/com/checkmarx/ast/IacRealtimeResultsTest.java b/src/test/java/com/checkmarx/ast/IacRealtimeResultsTest.java new file mode 100644 index 00000000..ce7c8b7f --- /dev/null +++ b/src/test/java/com/checkmarx/ast/IacRealtimeResultsTest.java @@ -0,0 +1,60 @@ +package com.checkmarx.ast; + +import com.checkmarx.ast.iacrealtime.IacRealtimeResults; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class IacRealtimeResultsTest { + + @Test + void testFromLineWithValidJsonArray() { + String json = "[" + + " {" + + " \"Title\": \"My Issue\"," + + " \"Severity\": \"High\"" + + " }" + + "]"; + IacRealtimeResults results = IacRealtimeResults.fromLine(json); + assertNotNull(results); + assertEquals(1, results.getResults().size()); + IacRealtimeResults.Issue issue = results.getResults().get(0); + assertEquals("My Issue", issue.getTitle()); + assertEquals("High", issue.getSeverity()); + } + + @Test + void testFromLineWithValidJsonObject() { + String json = "{" + + " \"Title\": \"My Single Issue\"," + + " \"Severity\": \"Medium\"" + + "}"; + IacRealtimeResults results = IacRealtimeResults.fromLine(json); + assertNotNull(results); + assertEquals(1, results.getResults().size()); + IacRealtimeResults.Issue issue = results.getResults().get(0); + assertEquals("My Single Issue", issue.getTitle()); + assertEquals("Medium", issue.getSeverity()); + } + + @Test + void testFromLineWithEmptyJsonArray() { + String json = "[]"; + IacRealtimeResults results = IacRealtimeResults.fromLine(json); + assertNotNull(results); + assertTrue(results.getResults().isEmpty()); + } + + @Test + void testFromLineWithBlankLine() { + assertNull(IacRealtimeResults.fromLine("")); + assertNull(IacRealtimeResults.fromLine(" ")); + assertNull(IacRealtimeResults.fromLine(null)); + } + + @Test + void testFromLineWithInvalidJson() { + String json = "[{]"; + assertNull(IacRealtimeResults.fromLine(json)); + } +} + diff --git a/src/test/java/com/checkmarx/ast/MaskTest.java b/src/test/java/com/checkmarx/ast/MaskTest.java new file mode 100644 index 00000000..ad188d21 --- /dev/null +++ b/src/test/java/com/checkmarx/ast/MaskTest.java @@ -0,0 +1,105 @@ +package com.checkmarx.ast; + +import com.checkmarx.ast.mask.MaskResult; +import com.checkmarx.ast.mask.MaskedSecret; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class MaskTest extends BaseTest { + + private static final String RESULTS_FILE = "target/test-classes/results.json"; + private static final String SECRETS_REALTIME_FILE = "target/test-classes/Secrets-realtime.json"; + + @Test + void testMaskSecretsWithFileContainingSecrets() throws Exception { + // Tests CLI execution with file containing actual secrets and validates masking behavior + MaskResult result = wrapper.maskSecrets(SECRETS_REALTIME_FILE); + + Assertions.assertNotNull(result); + Assertions.assertNotNull(result.getMaskedFile()); + Assertions.assertNotNull(result.getMaskedSecrets()); + Assertions.assertFalse(result.getMaskedSecrets().isEmpty()); + + MaskedSecret secret = result.getMaskedSecrets().get(0); + Assertions.assertNotNull(secret.getMasked()); + Assertions.assertNotNull(secret.getSecret()); + Assertions.assertEquals(5, secret.getLine()); + Assertions.assertTrue(secret.getMasked().contains("") || secret.getMasked().contains("\\u003cmasked\\u003e")); + Assertions.assertTrue(secret.getSecret().contains("-----BEGIN RSA PRIVATE KEY-----")); + Assertions.assertTrue(secret.getSecret().length() > secret.getMasked().length()); + } + + @Test + void testMaskSecretsWithFileContainingNoSecrets() throws Exception { + // Tests CLI execution with file containing no secrets + MaskResult result = wrapper.maskSecrets(RESULTS_FILE); + + Assertions.assertNotNull(result); + Assertions.assertNotNull(result.getMaskedFile()); + Assertions.assertFalse(result.getMaskedFile().isEmpty()); + } + + @Test + void testMaskSecretsErrorHandling() { + // Tests CLI error handling for invalid inputs + Assertions.assertThrows(Exception.class, () -> wrapper.maskSecrets(null)); + Assertions.assertThrows(Exception.class, () -> wrapper.maskSecrets("non-existent-file.json")); + Assertions.assertDoesNotThrow(() -> wrapper.maskSecrets(RESULTS_FILE)); + } + + @Test + void testMaskSecretsResponseParsing() throws Exception { + // Tests CLI response structure and JSON parsing functionality + MaskResult result = wrapper.maskSecrets(SECRETS_REALTIME_FILE); + + Assertions.assertNotNull(result); + Assertions.assertNotNull(result.getMaskedSecrets()); + Assertions.assertFalse(result.getMaskedSecrets().isEmpty()); + + MaskedSecret secret = result.getMaskedSecrets().get(0); + Assertions.assertNotNull(secret.getMasked()); + Assertions.assertNotNull(secret.getSecret()); + Assertions.assertTrue(secret.getLine() >= 0); + + Assertions.assertNull(MaskResult.fromLine("")); + Assertions.assertNull(MaskResult.fromLine("{invalid json}")); + Assertions.assertNull(MaskResult.fromLine(null)); + } + + @Test + void testMaskSecretsObjectBehavior() throws Exception { + // Tests object equality, serialization and consistency with CLI responses + MaskResult result1 = wrapper.maskSecrets(SECRETS_REALTIME_FILE); + MaskResult result2 = wrapper.maskSecrets(SECRETS_REALTIME_FILE); + + Assertions.assertEquals(result1.getMaskedFile(), result2.getMaskedFile()); + Assertions.assertNotNull(result1.toString()); + Assertions.assertTrue(result1.toString().contains("MaskResult")); + + if (result1.getMaskedSecrets() != null && !result1.getMaskedSecrets().isEmpty()) { + MaskedSecret secret1 = result1.getMaskedSecrets().get(0); + MaskedSecret secret2 = result2.getMaskedSecrets().get(0); + + Assertions.assertEquals(secret1.getMasked(), secret2.getMasked()); + Assertions.assertEquals(secret1.getSecret(), secret2.getSecret()); + Assertions.assertEquals(secret1.getLine(), secret2.getLine()); + Assertions.assertEquals(secret1.hashCode(), secret2.hashCode()); + Assertions.assertEquals(secret1, secret1); + Assertions.assertNotEquals(secret1, null); + + String toString = secret1.toString(); + Assertions.assertNotNull(toString); + Assertions.assertTrue(toString.contains("MaskedSecret")); + } + + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(result1); + MaskResult deserialized = mapper.readValue(json, MaskResult.class); + + Assertions.assertEquals(result1.getMaskedFile(), deserialized.getMaskedFile()); + if (result1.getMaskedSecrets() != null) { + Assertions.assertEquals(result1.getMaskedSecrets().size(), deserialized.getMaskedSecrets().size()); + } + } +} diff --git a/src/test/java/com/checkmarx/ast/OssRealtimeParsingTest.java b/src/test/java/com/checkmarx/ast/OssRealtimeParsingTest.java new file mode 100644 index 00000000..6ea0fea0 --- /dev/null +++ b/src/test/java/com/checkmarx/ast/OssRealtimeParsingTest.java @@ -0,0 +1,157 @@ +package com.checkmarx.ast; + +import com.checkmarx.ast.ossrealtime.OssRealtimeResults; +import com.checkmarx.ast.ossrealtime.OssRealtimeScanPackage; +import org.junit.jupiter.api.*; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Integration tests for OSS Realtime scanner functionality. + * Tests the complete workflow: CLI invocation -> JSON parsing -> domain object mapping. + * All tests use pom.xml as the scan target and are assumption-guarded for CI/local flexibility. + */ +class OssRealtimeParsingTest extends BaseTest { + + private boolean isCliConfigured() { + return Optional.ofNullable(getConfig().getPathToExecutable()).filter(s -> !s.isEmpty()).isPresent(); + } + + /** + * Tests basic OSS realtime scan functionality on pom.xml. + * Verifies that the scan returns a valid results object with detected Maven dependencies. + */ + @Test + @DisplayName("Basic OSS scan on pom.xml returns Maven dependencies") + void basicOssRealtimeScan() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + + OssRealtimeResults results = wrapper.ossRealtimeScan("pom.xml", ""); + + assertNotNull(results, "Scan should return non-null results"); + assertFalse(results.getPackages().isEmpty(), "Should detect Maven dependencies in pom.xml"); + + // Verify each package has required fields populated + results.getPackages().forEach(pkg -> { + assertNotNull(pkg.getPackageName(), "Package name should be populated"); + assertNotNull(pkg.getStatus(), "Package status should be populated"); + }); + } + + /** + * Tests OSS scan with ignore file functionality. + * Verifies that providing an ignore file reduces or maintains the package count compared to baseline scan. + */ + @Test + @DisplayName("OSS scan with ignore file filters packages correctly") + void ossRealtimeScanWithIgnoreFile() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String ignoreFile = "src/test/resources/ignored-packages.json"; + Assumptions.assumeTrue(Files.exists(Paths.get(ignoreFile)), "Ignore file not found - cannot test ignore functionality"); + + OssRealtimeResults baseline = wrapper.ossRealtimeScan("pom.xml", ""); + OssRealtimeResults filtered = wrapper.ossRealtimeScan("pom.xml", ignoreFile); + + assertNotNull(baseline, "Baseline scan should return results"); + assertNotNull(filtered, "Filtered scan should return results"); + assertTrue(filtered.getPackages().size() <= baseline.getPackages().size(), + "Filtered scan should have same or fewer packages than baseline"); + } + + /** + * Diagnostic test to see what package names are actually detected by the OSS scanner. + * This helps identify the correct package names for ignore file testing. + */ + @Test + @DisplayName("Display detected package names for diagnostic purposes") + void diagnosticPackageNames() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + + OssRealtimeResults results = wrapper.ossRealtimeScan("pom.xml", ""); + assertFalse(results.getPackages().isEmpty(), "Should have packages for diagnostic"); + + // Print package names for debugging (will show in test output) + System.out.println("Detected package names:"); + results.getPackages().forEach(pkg -> + System.out.println(" - " + pkg.getPackageName() + " (Manager: " + pkg.getPackageManager() + ")") + ); + + // This test always passes - it's just for information gathering + assertTrue(true, "Diagnostic test completed"); + } + + /** + * Tests that specific packages listed in ignore file are actually excluded from scan results. + * Uses a more flexible approach to find packages that can be ignored. + */ + @Test + @DisplayName("Ignore file excludes detected packages correctly") + void ignoreFileExcludesPackages() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String ignoreFile = "src/test/resources/ignored-packages.json"; + Assumptions.assumeTrue(Files.exists(Paths.get(ignoreFile)), "Ignore file not found - cannot test ignore functionality"); + + OssRealtimeResults baseline = wrapper.ossRealtimeScan("pom.xml", ""); + OssRealtimeResults filtered = wrapper.ossRealtimeScan("pom.xml", ignoreFile); + + // Look for common Maven packages that might be detected + String[] commonPackageNames = {"jackson-databind", "commons-lang3", "json-simple", "slf4j-simple", "junit-jupiter"}; + + boolean foundIgnoredPackage = false; + for (String packageName : commonPackageNames) { + boolean inBaseline = baseline.getPackages().stream() + .anyMatch(pkg -> packageName.equalsIgnoreCase(pkg.getPackageName())); + boolean inFiltered = filtered.getPackages().stream() + .anyMatch(pkg -> packageName.equalsIgnoreCase(pkg.getPackageName())); + + if (inBaseline && !inFiltered) { + foundIgnoredPackage = true; + System.out.println("Successfully filtered out package: " + packageName); + break; + } + } + assertTrue(filtered.getPackages().size() <= baseline.getPackages().size(), + "Filtered scan should not have more packages than baseline"); + } + + /** + * Tests scan consistency by running the same scan multiple times. + * Verifies that repeated scans of the same source produce stable, deterministic results. + */ + @Test + @DisplayName("Repeated OSS scans produce consistent results") + void ossRealtimeScanConsistency() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + + OssRealtimeResults firstScan = wrapper.ossRealtimeScan("pom.xml", ""); + OssRealtimeResults secondScan = wrapper.ossRealtimeScan("pom.xml", ""); + + assertEquals(firstScan.getPackages().size(), secondScan.getPackages().size(), + "Package count should be consistent across multiple scans"); + } + + /** + * Tests domain object mapping by verifying all expected package fields are properly populated. + * Ensures the JSON to POJO conversion works correctly for all package attributes. + */ + @Test + @DisplayName("Package domain objects are properly mapped from scan results") + void packageDomainObjectMapping() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + + OssRealtimeResults results = wrapper.ossRealtimeScan("pom.xml", ""); + assertFalse(results.getPackages().isEmpty(), "Should have packages to validate mapping"); + + OssRealtimeScanPackage samplePackage = results.getPackages().get(0); + + // Verify core package fields are mapped (some may be null based on scan results) + assertNotNull(samplePackage.getPackageName(), "Package name should always be present"); + assertNotNull(samplePackage.getStatus(), "Package status should always be present"); + assertNotNull(samplePackage.getLocations(), "Locations list should be initialized (may be empty)"); + assertNotNull(samplePackage.getVulnerabilities(), "Vulnerabilities list should be initialized (may be empty)"); + } +} diff --git a/src/test/java/com/checkmarx/ast/ScanTest.java b/src/test/java/com/checkmarx/ast/ScanTest.java index fb0b3b3b..5e31b337 100644 --- a/src/test/java/com/checkmarx/ast/ScanTest.java +++ b/src/test/java/com/checkmarx/ast/ScanTest.java @@ -3,7 +3,9 @@ import com.checkmarx.ast.asca.ScanDetail; import com.checkmarx.ast.asca.ScanResult; import com.checkmarx.ast.kicsRealtimeResults.KicsRealtimeResults; +import com.checkmarx.ast.ossrealtime.OssRealtimeResults; import com.checkmarx.ast.scan.Scan; +import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -92,4 +94,17 @@ void testKicsRealtimeScan() throws Exception { Assertions.assertTrue(scan.getResults().size() >= 1); } + @Test + void testOssRealtimeScanWithIgnoredFile() throws Exception { + Assumptions.assumeTrue(getConfig().getPathToExecutable() != null && !getConfig().getPathToExecutable().isEmpty(), "PATH_TO_EXECUTABLE not set"); + + String source = "pom.xml"; + String ignoreFile = "src/test/resources/ignored-packages.json"; + + OssRealtimeResults results = wrapper.ossRealtimeScan(source, ignoreFile); + + Assertions.assertNotNull(results); + Assertions.assertNotNull(results.getPackages()); + } + } diff --git a/src/test/java/com/checkmarx/ast/SecretsRealtimeResultsTest.java b/src/test/java/com/checkmarx/ast/SecretsRealtimeResultsTest.java new file mode 100644 index 00000000..a662d0f1 --- /dev/null +++ b/src/test/java/com/checkmarx/ast/SecretsRealtimeResultsTest.java @@ -0,0 +1,293 @@ +package com.checkmarx.ast; + +import com.checkmarx.ast.realtime.RealtimeLocation; +import com.checkmarx.ast.secretsrealtime.SecretsRealtimeResults; +import com.checkmarx.ast.wrapper.CxException; +import org.junit.jupiter.api.*; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Integration and unit tests for Secrets Realtime scanner functionality. + * Tests the complete workflow: CLI invocation -> JSON parsing -> domain object mapping. + * Integration tests use python-vul-file.py as the scan target and are assumption-guarded for CI/local flexibility. + */ +class SecretsRealtimeResultsTest extends BaseTest { + + private boolean isCliConfigured() { + return Optional.ofNullable(getConfig().getPathToExecutable()).filter(s -> !s.isEmpty()).isPresent(); + } + + /* ------------------------------------------------------ */ + /* Integration tests for Secrets Realtime scanning */ + /* ------------------------------------------------------ */ + + /** + * Tests basic secrets realtime scan functionality on a vulnerable Python file. + * Verifies that the scan returns a valid results object and can detect hardcoded secrets + * such as passwords and credentials embedded in the source code. + */ + @Test + @DisplayName("Basic secrets scan on python file returns detected secrets") + void basicSecretsRealtimeScan() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String pythonFile = "src/test/resources/python-vul-file.py"; + Assumptions.assumeTrue(Files.exists(Paths.get(pythonFile)), "Python vulnerable file not found - cannot test secrets scanning"); + + SecretsRealtimeResults results = wrapper.secretsRealtimeScan(pythonFile, ""); + + assertNotNull(results, "Scan should return non-null results"); + assertNotNull(results.getSecrets(), "Secrets list should be initialized"); + + // The python file contains hardcoded credentials, so we expect some secrets to be found + if (!results.getSecrets().isEmpty()) { + results.getSecrets().forEach(secret -> { + assertNotNull(secret.getTitle(), "Secret title should be populated"); + assertNotNull(secret.getFilePath(), "Secret file path should be populated"); + assertNotNull(secret.getLocations(), "Secret locations should be initialized"); + }); + } + } + + /** + * Tests secrets scan with ignore file functionality. + * Verifies that providing an ignore file doesn't break the scanning process + * and produces consistent or reduced results compared to baseline scan. + */ + @Test + @DisplayName("Secrets scan with ignore file works correctly") + void secretsRealtimeScanWithIgnoreFile() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String pythonFile = "src/test/resources/python-vul-file.py"; + String ignoreFile = "src/test/resources/ignored-packages.json"; + Assumptions.assumeTrue(Files.exists(Paths.get(pythonFile)) && Files.exists(Paths.get(ignoreFile)), + "Required test resources missing - cannot test ignore functionality"); + + SecretsRealtimeResults baseline = wrapper.secretsRealtimeScan(pythonFile, ""); + SecretsRealtimeResults filtered = wrapper.secretsRealtimeScan(pythonFile, ignoreFile); + + assertNotNull(baseline, "Baseline scan should return results"); + assertNotNull(filtered, "Filtered scan should return results"); + + // Ignore file should not increase the number of detected secrets + assertTrue(filtered.getSecrets().size() <= baseline.getSecrets().size(), + "Filtered scan should not have more secrets than baseline"); + } + + /** + * Tests scan consistency by running the same secrets scan multiple times. + * Verifies that repeated scans of the same file produce stable, deterministic results. + * This is crucial for ensuring reliable CI/CD pipeline integration. + */ + @Test + @DisplayName("Repeated secrets scans produce consistent results") + void secretsRealtimeScanConsistency() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String pythonFile = "src/test/resources/python-vul-file.py"; + Assumptions.assumeTrue(Files.exists(Paths.get(pythonFile)), "Python file not found - cannot test consistency"); + + SecretsRealtimeResults firstScan = wrapper.secretsRealtimeScan(pythonFile, ""); + SecretsRealtimeResults secondScan = wrapper.secretsRealtimeScan(pythonFile, ""); + + assertNotNull(firstScan, "First scan should return results"); + assertNotNull(secondScan, "Second scan should return results"); + + // Compare secret counts for consistency + assertEquals(firstScan.getSecrets().size(), secondScan.getSecrets().size(), + "Secret count should be consistent across multiple scans"); + } + + /** + * Tests domain object mapping for secrets scan results. + * Verifies that JSON responses are properly parsed into domain objects + * and all expected fields (title, description, severity, locations) are correctly mapped. + */ + @Test + @DisplayName("Secret domain objects are properly mapped from scan results") + void secretDomainObjectMapping() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String pythonFile = "src/test/resources/python-vul-file.py"; + Assumptions.assumeTrue(Files.exists(Paths.get(pythonFile)), "Python file not found - cannot test mapping"); + + SecretsRealtimeResults results = wrapper.secretsRealtimeScan(pythonFile, ""); + assertNotNull(results, "Scan results should not be null"); + + // If secrets are detected, validate their structure + if (!results.getSecrets().isEmpty()) { + SecretsRealtimeResults.Secret sampleSecret = results.getSecrets().get(0); + + // Verify core secret fields are mapped correctly + assertNotNull(sampleSecret.getTitle(), "Secret title should always be present"); + assertNotNull(sampleSecret.getFilePath(), "Secret file path should always be present"); + assertNotNull(sampleSecret.getLocations(), "Locations list should be initialized"); + + // Verify locations have proper structure if they exist + if (!sampleSecret.getLocations().isEmpty()) { + RealtimeLocation sampleLocation = sampleSecret.getLocations().get(0); + assertTrue(sampleLocation.getLine() > 0, "Line number should be positive"); + } + } + } + + /** + * Tests secrets scanning on a clean file that should not contain secrets. + * Verifies that the scanner correctly identifies files without secrets + * and returns empty results without errors. + */ + @Test + @DisplayName("Secrets scan on clean file returns empty results") + void secretsScanOnCleanFile() throws Exception { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + String cleanFile = "src/test/resources/csharp-no-vul.cs"; + Assumptions.assumeTrue(Files.exists(Paths.get(cleanFile)), "Clean C# file not found - cannot test clean scan"); + + SecretsRealtimeResults results = wrapper.secretsRealtimeScan(cleanFile, ""); + assertNotNull(results, "Scan results should not be null even for clean files"); + + // Clean file should have no secrets or very few false positives + assertTrue(results.getSecrets().size() <= 2, + "Clean file should have no or minimal secrets detected"); + } + + /** + * Tests error handling when scanning a non-existent file. + * Verifies that the scanner properly throws a CxException with meaningful error message + * when provided with invalid file paths, demonstrating proper error handling. + */ + @Test + @DisplayName("Secrets scan throws appropriate exception for non-existent file") + void secretsScanHandlesInvalidPath() { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + + // Test with a non-existent file path + String invalidPath = "src/test/resources/NonExistentFile.py"; + + // The CLI should throw a CxException with a meaningful error message for invalid paths + CxException exception = assertThrows(CxException.class, () -> + wrapper.secretsRealtimeScan(invalidPath, "") + ); + + // Verify the exception contains information about the invalid file path + String errorMessage = exception.getMessage(); + assertNotNull(errorMessage, "Exception should contain an error message"); + assertTrue(errorMessage.contains("invalid file path") || errorMessage.contains("file") || errorMessage.contains("path"), + "Exception message should indicate the issue is related to file path: " + errorMessage); + } + + /** + * Tests secrets scanning across multiple file types. + * Verifies that the scanner can handle different file extensions and formats + * without crashing and produces appropriate results for each file type. + */ + @Test + @DisplayName("Secrets scan handles multiple file types correctly") + void secretsScanMultipleFileTypes() { + Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test"); + + String[] testFiles = { + "src/test/resources/python-vul-file.py", + "src/test/resources/csharp-file.cs", + "src/test/resources/Dockerfile" + }; + + for (String filePath : testFiles) { + if (Files.exists(Paths.get(filePath))) { + assertDoesNotThrow(() -> { + SecretsRealtimeResults results = wrapper.secretsRealtimeScan(filePath, ""); + assertNotNull(results, "Results should not be null for file: " + filePath); + }, "Scanner should handle file type gracefully: " + filePath); + } + } + } + + + /* ------------------------------------------------------ */ + /* Unit tests for JSON parsing robustness */ + /* ------------------------------------------------------ */ + + /** + * Tests JSON parsing with valid secrets scan response containing array format. + * Verifies that well-formed JSON arrays are correctly parsed into domain objects. + */ + @Test + @DisplayName("Valid JSON array parsing creates correct domain objects") + void testFromLineWithJsonArray() { + String json = "[" + + "{" + + "\"Title\":\"Hardcoded AWS Access Key\"," + + "\"Description\":\"An AWS access key is hardcoded in the source code. This is a security risk.\"," + + "\"SecretValue\":\"AKIAIOSFODNN7EXAMPLE\"," + + "\"FilePath\":\"/path/to/file.py\"," + + "\"Severity\":\"HIGH\"," + + "\"Locations\":[{\"StartLine\":10,\"StartColumn\":5,\"EndLine\":10,\"EndColumn\":25}]" + + "}" + + "]"; + SecretsRealtimeResults results = SecretsRealtimeResults.fromLine(json); + assertNotNull(results); + assertEquals(1, results.getSecrets().size()); + SecretsRealtimeResults.Secret secret = results.getSecrets().get(0); + assertEquals("Hardcoded AWS Access Key", secret.getTitle()); + assertEquals("An AWS access key is hardcoded in the source code. This is a security risk.", secret.getDescription()); + assertEquals("AKIAIOSFODNN7EXAMPLE", secret.getSecretValue()); + assertEquals("/path/to/file.py", secret.getFilePath()); + assertEquals("HIGH", secret.getSeverity()); + assertEquals(1, secret.getLocations().size()); + } + + /** + * Tests JSON parsing with valid secrets scan response containing single object format. + * Verifies that single JSON objects are correctly parsed into domain objects. + */ + @Test + @DisplayName("Valid JSON object parsing creates correct domain objects") + void testFromLineWithJsonObject() { + String json = "{" + + "\"Title\":\"Hardcoded AWS Access Key\"," + + "\"Description\":\"An AWS access key is hardcoded in the source code. This is a security risk.\"," + + "\"SecretValue\":\"AKIAIOSFODNN7EXAMPLE\"," + + "\"FilePath\":\"/path/to/file.py\"," + + "\"Severity\":\"HIGH\"," + + "\"Locations\":[{\"StartLine\":10,\"StartColumn\":5,\"EndLine\":10,\"EndColumn\":25}]" + + "}"; + SecretsRealtimeResults results = SecretsRealtimeResults.fromLine(json); + assertNotNull(results); + assertEquals(1, results.getSecrets().size()); + SecretsRealtimeResults.Secret secret = results.getSecrets().get(0); + assertEquals("Hardcoded AWS Access Key", secret.getTitle()); + } + + /** + * Tests parsing robustness with malformed JSON and edge cases. + * Verifies that the parser gracefully handles various invalid input scenarios. + */ + @Test + @DisplayName("Malformed JSON and edge cases are handled gracefully") + void testFromLineWithEdgeCases() { + // Blank/null inputs + assertNull(SecretsRealtimeResults.fromLine("")); + assertNull(SecretsRealtimeResults.fromLine(" ")); + assertNull(SecretsRealtimeResults.fromLine(null)); + + // Invalid JSON structures + assertNull(SecretsRealtimeResults.fromLine("{")); + assertNull(SecretsRealtimeResults.fromLine("not a json")); + } + + /** + * Tests parsing with empty results. + * Verifies that empty JSON arrays are handled correctly and produce valid empty results. + */ + @Test + @DisplayName("Empty JSON arrays are handled correctly") + void testFromLineWithEmptyResults() { + String emptyJson = "[]"; + SecretsRealtimeResults results = SecretsRealtimeResults.fromLine(emptyJson); + assertNotNull(results); + assertTrue(results.getSecrets().isEmpty()); + } +} + diff --git a/src/test/java/com/checkmarx/ast/TenantTest.java b/src/test/java/com/checkmarx/ast/TenantTest.java index b9ac752c..7f49da16 100644 --- a/src/test/java/com/checkmarx/ast/TenantTest.java +++ b/src/test/java/com/checkmarx/ast/TenantTest.java @@ -11,11 +11,17 @@ public class TenantTest extends BaseTest { @Test void testTenantSettings() throws Exception { List tenantSettings = wrapper.tenantSettings(); - Assertions.assertTrue(tenantSettings.size() > 0); + Assertions.assertFalse(tenantSettings.isEmpty()); } @Test void testIdeScansEnabled() { Assertions.assertDoesNotThrow(() -> wrapper.ideScansEnabled()); } + + @Test + void testAiMcpServerEnabled() throws Exception { + boolean enabled = Assertions.assertDoesNotThrow(() -> wrapper.aiMcpServerEnabled()); + Assertions.assertTrue(enabled, "AI MCP Server flag expected to be true"); + } } diff --git a/src/test/resources/Secrets-realtime.json b/src/test/resources/Secrets-realtime.json new file mode 100644 index 00000000..5acdd938 --- /dev/null +++ b/src/test/resources/Secrets-realtime.json @@ -0,0 +1,147 @@ +[ + { + "Title": "private-key", + "Description": "Identified a Private Key, which may compromise cryptographic security and sensitive data encryption.", + "SecretValue": "-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAl5X22d9tXl2Bz1b+3mWsAouoBiQhrDS3GxFAdpJFkKF6Wst+Vl1mfshTd+gF2kHXTzLMdxsUM2AS8laG2xeIhLe07FhhOtQGSoAOjHD++K53MBcOD/mDVOlPhNOWAc3qWfa3R7ohxUJq8lvy1OErw7qlQv9U+xABUJtHbJtMn/dDBs1Fy6MUgO6TOtEwzQaTaGpWh3NmGaUu3KQuaekHZnzlYd8mc1XkztXrph0XxZPq43Gg8RVh25fCrcA+7iAkqa4MNL/5gsatzzjP7KRdx1IP0pnM6F/cwoMClmuV7FFhKoP3KFwt8SXglZnqLrCNK6DzrYU5bRaszIxYc8egywIDAQABAoIBADGaq2rkiF+m7cGx0Dlqv/0dQmCwFizKG1lKLfQfLZCEpwtrJ+6PJek7GMVWMgQYI6MRFoOrYtLlD44p7ntnmg8EJrpouXiMxXo/qYMfvvAV937PLJThq65vosvuiVoRziyeZZ+dM0vfzit9F1u+S5oDS+0+rMpzlFqSVa8eqtZ1i4wmVwKXF35FqHyzhXgKmVNXUy/JCiftJYF2hpe2zXAuGQKTD5x3v52GX+cUsRPPAO5GhJbDnwhbL8i06gLDc7xwfaTJbebvOKHT1F2AW/RhoW+BpJke86beea8DM7KR8RYjobgdf66fadosa27u8qqpcdtyzYMqLc3GuTeYL/ECgYEA36KgaxlWNCuQhLOLPZ/2fzebD1SCI7HsPtbiM+mSbWTGBnSPX36b1XLJkynZrAFKYoe9zx9ksqlrBHWG7PC3FLeIO9ExV9BsGFGjzDpkENteArcO5eLfSMkfXIXNlWwhb8m8DPjdnK2pihs3vVN0OMIPeYu9mAXst0CcR8vQuJ0CgYEArYYBgmAyWfRs8exU2F7vQoG8B4mykTOQ9J91Js72WiHaqt+z4NdGJrFr5VkXCZdbBf3J/PfEPVFT3ud/dAm2PZ40TfNQJTa4pwBhuyCozZff1Qm+X5NdzvHkLePFex6wxUgupVwr/W9UOVU7gRFB/hziSLnlglfpgwxA9j9tfocCgYEAqH69YzQp0RDpyDIGvR2i+WMJ/1jq3L4Xg5kfwYFAhA+jbAWyaH7aJs5ftfOYP5KRWv9vMXkzw7EGIsvyJt+O8Zr+mCMbjFBKwV/xi9SKxHCjumP2Y5q2JP70FB/0L5rS7okOmK+BOaVW0emD66/PJ1x/kFKLPNlp6wBRP37++bkCgYAgrkdkfaeeB4npOmB0a9TWCscWCFoIPNUFLW8MAxikuxGK8xzWsNS2ft3aUSAkn0v2YekD6sob3lBUf/ciLJ4VFtG1CKlEiPzX/xto+eqw5fSzE+W17HRTgH1AI1DTMmGKlmCqpiRm0+vh7GqLkWuDZ386wUA3f0UseEdX2XROywKBgE1Xer2yEZtLlrubHgVAKVrz2u5ZCEPzDkLEDhOxX2h1dP19TWvm2Sr6Fm1QL8lez52YhCW/xJHsr8S4Kka3Ntbm9+ZfhhATTICTpqIicqeAq/Iiw++7UgCk1gZPW1hnlDHYRdmI4Dr6j5aUBFLl4Bj2nedH+1L1Eo8EXfnjm0pi-----END RSA PRIVATE KEY-----", + "FilePath": "C:\\Users\\XYZ\\GitHub_Repo\\JavaVulnerableLab\\CxAppMonDeploy.pem", + "Severity": "High", + "Locations": [ + { + "Line": 0, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 1, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 2, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 3, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 4, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 5, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 6, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 7, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 8, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 9, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 10, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 11, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 12, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 13, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 14, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 15, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 16, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 17, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 18, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 19, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 20, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 21, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 22, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 23, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 24, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 25, + "StartIndex": 1, + "EndIndex": 30 + }, + { + "Line": 26, + "StartIndex": 1, + "EndIndex": 30 + } + ] + } +] + diff --git a/src/test/resources/ignored-packages.json b/src/test/resources/ignored-packages.json new file mode 100644 index 00000000..5ec153d5 --- /dev/null +++ b/src/test/resources/ignored-packages.json @@ -0,0 +1,5 @@ +[ + {"name": "jackson-databind", "version": "*"}, + {"name": "commons-lang3", "version": "*"}, + {"name": "json-simple", "version": "*"} +] From 87bb7ad5b615f190eb9369f2718065532aaad425 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 15 Dec 2025 09:54:19 +0000 Subject: [PATCH 31/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index ab37b459..e9d7a345 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64460df9a00bcc48a599688c878ddabe20187127f5f7e0fb84cee08abc21120f -size 80982200 +oid sha256:e85a01c5b935cc35dedb741d4ef04f6ea92880ae6e589011ccb1a2a811560e57 +size 81002680 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index dbedcd93..b0fcdc0a 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:823ba8fb7a41df2198af4371c1868d06e8ec1116cc8c98a1a6ba2e1502fa6090 +oid sha256:f3ed3534e09fb4be79cd0e79b51a959e1e712a1662af066e4d6421772e2a0847 size 77267128 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index b4b2df59..52a08116 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ab046570766900b90ca6412175eb60096bbbc1b251142237f4f836f54afb56be -size 162864288 +oid sha256:ced61dca25a0be25447308e6adde3990aba73589cb638b9845f2e961c93c8499 +size 162954864 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index a62fc095..95849445 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:606e331a9a722cf2668e6f8e09966f0972e483c3a2a1135277172194604b8195 -size 82958272 +oid sha256:bf0e0f8c3a721f9e2e21671e9a1954d9ac132a6621c076e467e1bfd51b9a2269 +size 82975168 From bfcd1602c92000cc76da0c065853937fff88786c Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Mon, 15 Dec 2025 09:54:20 +0000 Subject: [PATCH 32/42] Update checkmarx-ast-cli to 2.3.41 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index 0f1c3e55..81309a31 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.40 +2.3.41 From f27370c5db7c410c3ea6477ac128fa5f4a3941d4 Mon Sep 17 00:00:00 2001 From: Atish Jadhav <141334503+cx-atish-jadhav@users.noreply.github.com> Date: Mon, 29 Dec 2025 16:57:22 +0530 Subject: [PATCH 33/42] Add Telemetry AI event support to Java wrapper with test coverage (AST-127560) (#454) * aimcp server changes * oss-realtime scanner changes * Create OssRealtimeVulnerability.java * Unify realtime scan wrappers; consolidate Secrets/IaC models; deprecate and stub obsolete result classes * Add ContainersRealtimeVulnerability model for containers realtime scan parsing * Add @JsonCreator constructor to OssRealtimeVulnerability for reliable Jackson deserialization * Refactoring package name and adding test for oss and mcp flag * Add integration tests for OSS, Container, and Secrets realtime scanners * Replaced Id to CVE in oss vulnerability * Changed variable from id to CVE as per OSS response * aimcp server changes * oss-realtime scanner changes * Create OssRealtimeVulnerability.java * Unify realtime scan wrappers; consolidate Secrets/IaC models; deprecate and stub obsolete result classes * Add ContainersRealtimeVulnerability model for containers realtime scan parsing * Add @JsonCreator constructor to OssRealtimeVulnerability for reliable Jackson deserialization * Refactoring package name and adding test for oss and mcp flag * Add integration tests for OSS, Container, and Secrets realtime scanners * Changed variable from id to CVE as per OSS response * Add maskedResult for secret remediation and change log level from INFO to DEBUG * Remove masked secrets functionality from codebase * Implemented mask cmd in java wrapper * Added fix for containerTool for IAC * Add telemetry AI command with full parameter support and tests * Add ignoredFilePath parameter to ScanAsca method * Removing ASCA ignore file path changes --------- Co-authored-by: cx-anand-nandeshwar <73646287+cx-anand-nandeshwar@users.noreply.github.com> Co-authored-by: anjali-deore <200181980+cx-anjali-deore@users.noreply.github.com> --- .../checkmarx/ast/wrapper/CxConstants.java | 9 +++ .../com/checkmarx/ast/wrapper/CxWrapper.java | 67 ++++++++++++++++--- .../java/com/checkmarx/ast/TelemetryTest.java | 67 +++++++++++++++++++ 3 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 src/test/java/com/checkmarx/ast/TelemetryTest.java diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java index dd8c6e69..79f171c2 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java @@ -82,4 +82,13 @@ public final class CxConstants { static final String SUB_CMD_CONTAINERS_REALTIME = "containers-realtime"; static final String SUB_CMD_MASK = "mask"; static final String RESULT_FILE = "--result-file"; + static final String CMD_TELEMETRY = "telemetry"; + static final String SUB_CMD_TELEMETRY_AI = "ai"; + static final String AI_PROVIDER = "--ai-provider"; + static final String TYPE = "--type"; + static final String SUB_TYPE = "--sub-type"; + static final String PROBLEM_SEVERITY = "--problem-severity"; + static final String SCAN_TYPE_FLAG = "--scan-type"; + static final String STATUS = "--status"; + static final String TOTAL_COUNT = "--total-count"; } diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java index c49aa875..386133ad 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java @@ -409,7 +409,7 @@ public KicsRealtimeResults kicsRealtimeScan(@NonNull String fileSources, String return Execution.executeCommand(withConfigArguments(arguments), logger, KicsRealtimeResults::fromLine); } - public T realtimeScan(@NonNull String subCommand, @NonNull String sourcePath, String ignoredFilePath, java.util.function.Function resultParser) + public T realtimeScan(@NonNull String subCommand, @NonNull String sourcePath, String containerTool, String ignoredFilePath, java.util.function.Function resultParser) throws IOException, InterruptedException, CxException { this.logger.info("Executing 'scan {}' command using the CLI.", subCommand); this.logger.info("Source: {} IgnoredFilePath: {}", sourcePath, ignoredFilePath); @@ -418,6 +418,10 @@ public T realtimeScan(@NonNull String subCommand, @NonNull String sourcePath arguments.add(subCommand); arguments.add(CxConstants.SOURCE); arguments.add(sourcePath); + if(StringUtils.isNotBlank(containerTool)){ + arguments.add(CxConstants.ENGINE); + arguments.add(containerTool); + } if (StringUtils.isNotBlank(ignoredFilePath)) { arguments.add(CxConstants.IGNORED_FILE_PATH); arguments.add(ignoredFilePath); @@ -428,27 +432,26 @@ public T realtimeScan(@NonNull String subCommand, @NonNull String sourcePath // OSS Realtime public OssRealtimeResults ossRealtimeScan(@NonNull String sourcePath, String ignoredFilePath) throws IOException, InterruptedException, CxException { - return realtimeScan(CxConstants.SUB_CMD_OSS_REALTIME, sourcePath, ignoredFilePath, OssRealtimeResults::fromLine); + return realtimeScan(CxConstants.SUB_CMD_OSS_REALTIME, sourcePath,"", ignoredFilePath, OssRealtimeResults::fromLine); } // IAC Realtime - public IacRealtimeResults iacRealtimeScan(@NonNull String sourcePath, String ignoredFilePath) + public IacRealtimeResults iacRealtimeScan(@NonNull String sourcePath,String containerTool, String ignoredFilePath) throws IOException, InterruptedException, CxException { - return realtimeScan(CxConstants.SUB_CMD_IAC_REALTIME, sourcePath, ignoredFilePath, IacRealtimeResults::fromLine); + return realtimeScan(CxConstants.SUB_CMD_IAC_REALTIME, sourcePath,containerTool, ignoredFilePath, IacRealtimeResults::fromLine); } + // Secrets Realtime public SecretsRealtimeResults secretsRealtimeScan(@NonNull String sourcePath, String ignoredFilePath) throws IOException, InterruptedException, CxException { - return realtimeScan(CxConstants.SUB_CMD_SECRETS_REALTIME, sourcePath, ignoredFilePath, SecretsRealtimeResults::fromLine); + return realtimeScan(CxConstants.SUB_CMD_SECRETS_REALTIME, sourcePath,"", ignoredFilePath, SecretsRealtimeResults::fromLine); } - - // Containers Realtime public ContainersRealtimeResults containersRealtimeScan(@NonNull String sourcePath, String ignoredFilePath) throws IOException, InterruptedException, CxException { - return realtimeScan(CxConstants.SUB_CMD_CONTAINERS_REALTIME, sourcePath, ignoredFilePath, ContainersRealtimeResults::fromLine); + return realtimeScan(CxConstants.SUB_CMD_CONTAINERS_REALTIME, sourcePath, "",ignoredFilePath, ContainersRealtimeResults::fromLine); } public KicsRemediation kicsRemediate(@NonNull String resultsFile, String kicsFile, String engine,String similarityIds) @@ -534,6 +537,54 @@ public MaskResult maskSecrets(@NonNull String filePath) throws CxException, IOEx return Execution.executeCommand(withConfigArguments(arguments), logger, MaskResult::fromLine); } + /** + * Executes telemetry AI command to collect telemetry data for user interactions related to AI features. + * + * @param aiProvider AI provider name (e.g., "Copilot") + * @param agent Agent name (e.g., "Jetbrains") + * @param eventType Event type (e.g., "click") + * @param subType Event subtype (e.g., "ast-results.viewPackageDetails") + * @param engine Engine type (e.g., "secrets") + * @param problemSeverity Severity level (e.g., "high") + * @param scanType Type of scan + * @param status Status information + * @param totalCount Number count + * @return Command output as string + * @throws IOException if I/O error occurs + * @throws InterruptedException if command execution is interrupted + * @throws CxException if CLI command fails + */ + public String telemetryAIEvent(String aiProvider, String agent, String eventType, String subType, + String engine, String problemSeverity, String scanType, String status, + Integer totalCount) throws IOException, InterruptedException, CxException { + this.logger.info("Executing telemetry AI event with provider: {}, type: {}, subType: {}", + aiProvider, eventType, subType); + + List arguments = new ArrayList<>(); + arguments.add(CxConstants.CMD_TELEMETRY); + arguments.add(CxConstants.SUB_CMD_TELEMETRY_AI); + arguments.add(CxConstants.AI_PROVIDER); + arguments.add(aiProvider); + arguments.add(CxConstants.AGENT); + arguments.add(agent); + arguments.add(CxConstants.TYPE); + arguments.add(eventType); + arguments.add(CxConstants.SUB_TYPE); + arguments.add(subType); + arguments.add(CxConstants.ENGINE); + arguments.add(engine); + arguments.add(CxConstants.PROBLEM_SEVERITY); + arguments.add(problemSeverity); + arguments.add(CxConstants.SCAN_TYPE_FLAG); + arguments.add(scanType); + arguments.add(CxConstants.STATUS); + arguments.add(status); + arguments.add(CxConstants.TOTAL_COUNT); + arguments.add(totalCount.toString()); + + return Execution.executeCommand(withConfigArguments(arguments), logger, line -> line); + } + private int getIndexOfBfLNode(List bflNodes, List resultNodes) { int bflNodeNotFound = -1; diff --git a/src/test/java/com/checkmarx/ast/TelemetryTest.java b/src/test/java/com/checkmarx/ast/TelemetryTest.java new file mode 100644 index 00000000..a014aa65 --- /dev/null +++ b/src/test/java/com/checkmarx/ast/TelemetryTest.java @@ -0,0 +1,67 @@ +package com.checkmarx.ast; + +import com.checkmarx.ast.wrapper.CxException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +/** + * Telemetry AI event test cases covering various parameter scenarios. + */ +class TelemetryTest extends BaseTest { + + @Test + void testTelemetryAIEventSuccessfulCaseWithMinimalParametersAiLog() throws CxException, IOException, InterruptedException { + // Test case: AI logging with specific parameters and some empty values + Assertions.assertDoesNotThrow(() -> { + String result = wrapper.telemetryAIEvent( + "Cursor", // aiProvider + "Cursos", // agent + "click", // eventType + "ast-results.viewPackageDetails", // subType + "secrets", // engine + "high", // problemSeverity + "", // scanType (empty) + "", // status (empty) + 0 // totalCount + ); + }, "Telemetry AI event should execute successfully"); + } + + @Test + void testTelemetryAIEventSuccessfulCaseWithMinimalParametersDetectionLog() throws CxException, IOException, InterruptedException { + // Test case: Detection logging with most parameters empty and specific scan data + Assertions.assertDoesNotThrow(() -> { + String result = wrapper.telemetryAIEvent( + "", // aiProvider (empty) + "", // agent (empty) + "", // eventType (empty) + "", // subType (empty) + "", // engine (empty) + "", // problemSeverity (empty) + "asca", // scanType + "Critical", // status + 10 // totalCount + ); + }, "Telemetry AI event should execute successfully for detection log"); + } + + @Test + void testTelemetryAIEventSuccessfulCaseWithEdgeCaseParameters() throws CxException, IOException, InterruptedException { + // Test case: Edge case with minimal required parameters + Assertions.assertDoesNotThrow(() -> { + String result = wrapper.telemetryAIEvent( + "test-provider", // aiProvider (minimal value) + "java-wrapper", // agent (minimal value) + "", // eventType (empty) + "", // subType (empty) + "", // engine (empty) + "", // problemSeverity (empty) + "", // scanType (empty) + "", // status (empty) + 0 // totalCount + ); + }, "Telemetry AI event should execute successfully for edge case"); + } +} From 150032f8eee7dced12d44e9f58d18a20a3883f22 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 30 Dec 2025 14:59:27 +0000 Subject: [PATCH 34/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 4 ++-- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index e9d7a345..f9909fd8 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e85a01c5b935cc35dedb741d4ef04f6ea92880ae6e589011ccb1a2a811560e57 -size 81002680 +oid sha256:2972512d55630f04f494fdf3543a3edf37906b970f5e29f58127ad27c40b652c +size 81023160 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index b0fcdc0a..f17f02d5 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f3ed3534e09fb4be79cd0e79b51a959e1e712a1662af066e4d6421772e2a0847 -size 77267128 +oid sha256:ba3e45134be18e2093521df1f5e337c749e231fc926d5928815be4bbc68c4dd0 +size 77332664 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 52a08116..52f3f40f 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ced61dca25a0be25447308e6adde3990aba73589cb638b9845f2e961c93c8499 -size 162954864 +oid sha256:7da05ed86e02142c414ebfa2ed335b71357f7d407291b9952bf5860c7bf78dab +size 162975392 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 95849445..0341df07 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf0e0f8c3a721f9e2e21671e9a1954d9ac132a6621c076e467e1bfd51b9a2269 -size 82975168 +oid sha256:5fb41bc7c8d5b3db18f4626d9523fc626fd19c6f88e1bb078184e7b6e2532fed +size 82995136 From 35697d76fd95d04ffc0907f584c8e6f05abaf937 Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Tue, 30 Dec 2025 14:59:27 +0000 Subject: [PATCH 35/42] Update checkmarx-ast-cli to 2.3.42 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index 81309a31..e41ae218 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.41 +2.3.42 From c852cccb357861a9c1d683d1a7a638dd0ac72fcb Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 16 Jan 2026 12:12:11 +0000 Subject: [PATCH 36/42] Track Checkmarx CLI binaries with Git LFS --- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index f9909fd8..5bd22e20 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2972512d55630f04f494fdf3543a3edf37906b970f5e29f58127ad27c40b652c -size 81023160 +oid sha256:a2ec1fcc76f04596c976b5039ff8d755f3e6534f06ecf442cb8d22c4f3e8f9c8 +size 81055928 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index f17f02d5..fe820c8d 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba3e45134be18e2093521df1f5e337c749e231fc926d5928815be4bbc68c4dd0 +oid sha256:23dbe8b789c4c358023a98c15fdc57a468fff934804bbbfbb3ec5fa90d803c11 size 77332664 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 52f3f40f..5423173f 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7da05ed86e02142c414ebfa2ed335b71357f7d407291b9952bf5860c7bf78dab -size 162975392 +oid sha256:a0a89e14ad8516e093625d3eff5713c83696d12494664c338839731f8dd8a79e +size 163042800 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 0341df07..a71d0477 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5fb41bc7c8d5b3db18f4626d9523fc626fd19c6f88e1bb078184e7b6e2532fed -size 82995136 +oid sha256:3f73d920a720bd8c3a6f4f234a77589e51611f07645c53baf1650396f77ed4f3 +size 83032512 From 9ba9b3c174aa720b0a01fa8cb80972090a7e9d5e Mon Sep 17 00:00:00 2001 From: cx-anurag-dalke <120229307+cx-anurag-dalke@users.noreply.github.com> Date: Fri, 16 Jan 2026 12:12:11 +0000 Subject: [PATCH 37/42] Update checkmarx-ast-cli to 2.3.43 --- checkmarx-ast-cli.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index e41ae218..fcf4e515 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.42 +2.3.43 From d637137986d77322564facb09d53972564baedcd Mon Sep 17 00:00:00 2001 From: Anjali Deore <200181980+cx-anjali-deore@users.noreply.github.com> Date: Wed, 21 Jan 2026 19:05:10 +0530 Subject: [PATCH 38/42] Changes related to ignore/revive functionality (AST-109612) (#457) * aimcp server changes * oss-realtime scanner changes * Create OssRealtimeVulnerability.java * Unify realtime scan wrappers; consolidate Secrets/IaC models; deprecate and stub obsolete result classes * Add ContainersRealtimeVulnerability model for containers realtime scan parsing * Add @JsonCreator constructor to OssRealtimeVulnerability for reliable Jackson deserialization * Refactoring package name and adding test for oss and mcp flag * Add integration tests for OSS, Container, and Secrets realtime scanners * Replaced Id to CVE in oss vulnerability * Changed variable from id to CVE as per OSS response * aimcp server changes * oss-realtime scanner changes * Create OssRealtimeVulnerability.java * Unify realtime scan wrappers; consolidate Secrets/IaC models; deprecate and stub obsolete result classes * Add ContainersRealtimeVulnerability model for containers realtime scan parsing * Add @JsonCreator constructor to OssRealtimeVulnerability for reliable Jackson deserialization * Refactoring package name and adding test for oss and mcp flag * Add integration tests for OSS, Container, and Secrets realtime scanners * Changed variable from id to CVE as per OSS response * Add maskedResult for secret remediation and change log level from INFO to DEBUG * Remove masked secrets functionality from codebase * Implemented mask cmd in java wrapper * Added fix for containerTool for IAC * Add telemetry AI command with full parameter support and tests * Add ignoredFilePath parameter to ScanAsca method * Removing ASCA ignore file path changes * Add ignoredFilePath parameter to ScanAsca realtime * - Changed ast cli version * added-isdev-isoneassist-function * - Adding engine check * - Added check for engine verification in path * - Added checks message for exception * - Added checks message for exception * passing-agent-name-jb-in-all-cmd * merge-fix * placed-cli-exe * Revert "Merge branch 'main' into feature/ASCA_IgnoreFile" This reverts commit 7a6d22942a68521452cc27428cd1711ebead0cd3, reversing changes made to 8b47577209497e9e8edb4af514d9ae12255e9438. * Update checkmarx-ast-cli.version * - Added fallback for macOS engine detection * - Refactored code as per review comments --------- Co-authored-by: atishj99 <141334503+cx-atish-jadhav@users.noreply.github.com> Co-authored-by: cx-anand-nandeshwar <73646287+cx-anand-nandeshwar@users.noreply.github.com> Co-authored-by: Hitesh Madgulkar <212497904+cx-hitesh-madgulkar@users.noreply.github.com> --- .../com/checkmarx/ast/wrapper/CxConfig.java | 6 +- .../checkmarx/ast/wrapper/CxConstants.java | 6 + .../com/checkmarx/ast/wrapper/CxWrapper.java | 131 +++++++++++++++--- .../com/checkmarx/ast/wrapper/Execution.java | 10 +- src/main/resources/cx-linux | 4 +- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 +- src/main/resources/cx.exe | 4 +- src/test/java/com/checkmarx/ast/ScanTest.java | 19 ++- .../java/com/checkmarx/ast/TenantTest.java | 10 ++ 10 files changed, 158 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java b/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java index f23a5ea8..ab0a7329 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConfig.java @@ -16,7 +16,7 @@ public class CxConfig { private static final Pattern pattern = Pattern.compile("([^\"]\\S*|\".+?\")\\s*"); - + private String agentName; //JETBRAINS private String baseUri; private String baseAuthUri; private String tenant; @@ -66,6 +66,10 @@ List toArguments() { commands.add(CxConstants.BASE_AUTH_URI); commands.add(getBaseAuthUri()); } + if (getAgentName() != null && !getAgentName().isEmpty()) { + commands.add("--agent"); + commands.add(getAgentName()); + } if (getAdditionalParameters() != null) commands.addAll(getAdditionalParameters()); diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java index 79f171c2..26a11dd6 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java @@ -75,6 +75,8 @@ public final class CxConstants { static final String SUB_CMD_TENANT = "tenant"; static final String IDE_SCANS_KEY = "scan.config.plugins.ideScans"; static final String AI_MCP_SERVER_KEY = "scan.config.plugins.aiMcpServer"; + static final String DEV_ASSIST_LICENSE_KEY = "scan.config.plugins.cxdevassist"; + static final String ONE_ASSIST_LICENSE_KEY = "scan.config.plugins.cxoneassist"; static final String IGNORED_FILE_PATH = "--ignored-file-path"; static final String SUB_CMD_OSS_REALTIME = "oss-realtime"; static final String SUB_CMD_IAC_REALTIME = "iac-realtime"; @@ -91,4 +93,8 @@ public final class CxConstants { static final String SCAN_TYPE_FLAG = "--scan-type"; static final String STATUS = "--status"; static final String TOTAL_COUNT = "--total-count"; + static final String DOCKER = "docker"; + static final String PODMAN = "podman"; + static final String PODMAN_FALLBACK_PATH = "/usr/local/bin/podman"; + static final String DOCKER_FALLBACK_PATH = "/usr/local/bin/docker"; } diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java index 386133ad..1526d2b8 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java @@ -29,17 +29,22 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; + +import static com.checkmarx.ast.wrapper.Execution.*; public class CxWrapper { private static final CollectionType BRANCHES_TYPE = TypeFactory.defaultInstance() .constructCollectionType(List.class, String.class); + private static final String OS_LINUX = "linux"; + private static final String OS_WINDOWS = "windows"; + private static final String OS_MAC = "mac"; @NonNull private final CxConfig cxConfig; @@ -248,7 +253,7 @@ public List projectList(String filter) throws IOException, InterruptedE return Execution.executeCommand(withConfigArguments(arguments), logger, Project::listFromLine); } - public ScanResult ScanAsca(String fileSource, boolean ascaLatestVersion, String agent) throws IOException, InterruptedException, CxException { + public ScanResult ScanAsca(String fileSource, boolean ascaLatestVersion, String agent, String ignoredFilePath) throws IOException, InterruptedException, CxException { this.logger.info("Fetching ASCA scanResult"); List arguments = new ArrayList<>(); @@ -259,23 +264,27 @@ public ScanResult ScanAsca(String fileSource, boolean ascaLatestVersion, String if (ascaLatestVersion) { arguments.add(CxConstants.ASCA_LATEST_VERSION); } + if (StringUtils.isNotBlank(ignoredFilePath)) { + arguments.add(CxConstants.IGNORED_FILE_PATH); + arguments.add(ignoredFilePath); + } + - appendAgentToArguments(agent, arguments); return Execution.executeCommand(withConfigArguments(arguments), logger, ScanResult::fromLine, (args, ignored) -> (args.size() >= 3 && args.get(1).equals(CxConstants.CMD_SCAN) && args.get(2).equals(CxConstants.SUB_CMD_ASCA))); } - private static void appendAgentToArguments(String agent, List arguments) { - arguments.add(CxConstants.AGENT); - if (agent != null && !agent.isEmpty()){ - arguments.add(agent); - } - else{ - arguments.add("CLI-Java-Wrapper"); - } - } + // private static void appendAgentToArguments(String agent, List arguments) { + // arguments.add(CxConstants.AGENT); + // if (agent != null && !agent.isEmpty()){ + // arguments.add(agent); + // } + // else{ + // arguments.add("CLI-Java-Wrapper"); + // } + // } public List projectBranches(@NonNull UUID projectId, String filter) throws CxException, IOException, InterruptedException { @@ -345,10 +354,6 @@ public String results(@NonNull UUID scanId, ReportFormat reportFormat, String ag arguments.add(fileName); arguments.add(CxConstants.OUTPUT_PATH); arguments.add(tempDir); - if (agent != null) { - arguments.add(CxConstants.AGENT); - arguments.add(agent); - } return Execution.executeCommand(arguments, logger, tempDir, fileName + reportFormat.getExtension()); @@ -409,6 +414,68 @@ public KicsRealtimeResults kicsRealtimeScan(@NonNull String fileSources, String return Execution.executeCommand(withConfigArguments(arguments), logger, KicsRealtimeResults::fromLine); } + public String checkEngineExist(@NonNull String engineName) throws CxException, IOException, InterruptedException { + String osName = System.getProperty("os.name").toLowerCase(Locale.ENGLISH); + String osType=Execution.getOperatingSystemType(osName); + return this.checkEngine(engineName,osType); + } + + private String verifyEngineOnMAC(String engineName,Listarguments) throws CxException, IOException, InterruptedException { + Exception lastException = null; + String enginePath; + try{ + enginePath= Execution.executeCommand((arguments), logger, line->line); + return enginePath; + } catch (CxException | IOException e) { + lastException = e; + } + Path dockerPath = Paths.get(CxConstants.DOCKER_FALLBACK_PATH); + Path podmanPath = Paths.get(CxConstants.PODMAN_FALLBACK_PATH); + if (CxConstants.DOCKER.equalsIgnoreCase(engineName)) { + if (Files.isSymbolicLink(dockerPath)) { + return Files.readSymbolicLink(dockerPath).toAbsolutePath().toString(); + } + else { return dockerPath.toAbsolutePath().toString(); } + } + else if (CxConstants.PODMAN.equalsIgnoreCase(engineName)) { + if (Files.exists(podmanPath)) { + if (Files.isSymbolicLink(podmanPath)) { + return Files.readSymbolicLink(podmanPath).toAbsolutePath().toString(); + } + else{ + return podmanPath.toAbsolutePath().toString(); + } + } + } + throw new CxException( 1, "Engine '" + engineName + "' is not installed or not symlinked to /usr/local/bin." ); + } + + private String checkEngine(String engineName, String osType ) throws CxException, IOException, InterruptedException { + List arguments = new ArrayList<>(); + switch (osType){ + case OS_MAC: + arguments.add("/bin/sh"); + arguments.add("-c"); + arguments.add("command -v " + engineName); + return verifyEngineOnMAC(engineName,arguments); + case OS_WINDOWS: + case OS_LINUX: + arguments.add(engineName); + arguments.add("--version"); + try { + Execution.executeCommand(arguments, logger, line -> line); + return engineName; + } catch (CxException | IOException e) { + throw new CxException( + 1,engineName+" is not installed or is not accessible from the system PATH." + ); + } + default: + throw new IllegalArgumentException("Unsupported OS: " + osType); + } + + } + public T realtimeScan(@NonNull String subCommand, @NonNull String sourcePath, String containerTool, String ignoredFilePath, java.util.function.Function resultParser) throws IOException, InterruptedException, CxException { this.logger.info("Executing 'scan {}' command using the CLI.", subCommand); @@ -495,7 +562,7 @@ public List learnMore(String queryId) throws CxException, IOException public boolean ideScansEnabled() throws CxException, IOException, InterruptedException { List tenantSettings = tenantSettings(); - if (tenantSettings == null) { + if (tenantSettings == null || tenantSettings.isEmpty()) { throw new CxException(1, "Unable to parse tenant settings"); } return tenantSettings.stream() @@ -526,6 +593,28 @@ public List tenantSettings() throws CxException, IOException, Int return Execution.executeCommand(withConfigArguments(arguments), logger, TenantSetting::listFromLine); } + + + public boolean getTenantSetting(String key) throws CxException, IOException, InterruptedException { + List tenantSettings = tenantSettings(); + if (tenantSettings == null) { + throw new CxException(1, "Unable to parse tenant settings"); + } + return tenantSettings.stream() + .filter(t -> t.getKey().equals(key)) + .findFirst() + .map(t -> Boolean.parseBoolean(t.getValue())) + .orElse(false); + } + public boolean devAssistEnabled() throws CxException, IOException, InterruptedException { + return getTenantSetting(CxConstants.DEV_ASSIST_LICENSE_KEY); + + } + + public boolean oneAssistEnabled() throws CxException, IOException, InterruptedException { + return getTenantSetting(CxConstants.ONE_ASSIST_LICENSE_KEY); + } + public MaskResult maskSecrets(@NonNull String filePath) throws CxException, IOException, InterruptedException { List arguments = new ArrayList<>(); @@ -565,8 +654,6 @@ public String telemetryAIEvent(String aiProvider, String agent, String eventType arguments.add(CxConstants.SUB_CMD_TELEMETRY_AI); arguments.add(CxConstants.AI_PROVIDER); arguments.add(aiProvider); - arguments.add(CxConstants.AGENT); - arguments.add(agent); arguments.add(CxConstants.TYPE); arguments.add(eventType); arguments.add(CxConstants.SUB_TYPE); diff --git a/src/main/java/com/checkmarx/ast/wrapper/Execution.java b/src/main/java/com/checkmarx/ast/wrapper/Execution.java index c233ff2d..0a888ec0 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/Execution.java +++ b/src/main/java/com/checkmarx/ast/wrapper/Execution.java @@ -1,5 +1,6 @@ package com.checkmarx.ast.wrapper; +import com.checkmarx.ast.kicsRealtimeResults.KicsRealtimeResults; import lombok.NonNull; import org.slf4j.Logger; @@ -12,10 +13,7 @@ import java.nio.file.Paths; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Objects; +import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; @@ -171,7 +169,7 @@ private static String detectBinaryName(@NonNull Logger logger) { return fileName; } - private static String getOperatingSystemType(String osName) { + public static String getOperatingSystemType(String osName) { if (osName.contains(OS_LINUX)) { return OS_LINUX; } else if (osName.contains(OS_WINDOWS)) { @@ -217,4 +215,6 @@ private static String md5(InputStream a) { } return md5; } + + } diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 5bd22e20..f9909fd8 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2ec1fcc76f04596c976b5039ff8d755f3e6534f06ecf442cb8d22c4f3e8f9c8 -size 81055928 +oid sha256:2972512d55630f04f494fdf3543a3edf37906b970f5e29f58127ad27c40b652c +size 81023160 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index fe820c8d..f17f02d5 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:23dbe8b789c4c358023a98c15fdc57a468fff934804bbbfbb3ec5fa90d803c11 +oid sha256:ba3e45134be18e2093521df1f5e337c749e231fc926d5928815be4bbc68c4dd0 size 77332664 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 5423173f..52f3f40f 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0a89e14ad8516e093625d3eff5713c83696d12494664c338839731f8dd8a79e -size 163042800 +oid sha256:7da05ed86e02142c414ebfa2ed335b71357f7d407291b9952bf5860c7bf78dab +size 162975392 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index a71d0477..0341df07 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f73d920a720bd8c3a6f4f234a77589e51611f07645c53baf1650396f77ed4f3 -size 83032512 +oid sha256:5fb41bc7c8d5b3db18f4626d9523fc626fd19c6f88e1bb078184e7b6e2532fed +size 82995136 diff --git a/src/test/java/com/checkmarx/ast/ScanTest.java b/src/test/java/com/checkmarx/ast/ScanTest.java index 5e31b337..a414281e 100644 --- a/src/test/java/com/checkmarx/ast/ScanTest.java +++ b/src/test/java/com/checkmarx/ast/ScanTest.java @@ -25,7 +25,7 @@ void testScanShow() throws Exception { @Test void testScanAsca_WhenFileWithVulnerabilitiesIsSentWithAgent_ReturnSuccessfulResponseWithCorrectValues() throws Exception { - ScanResult scanResult = wrapper.ScanAsca("src/test/resources/python-vul-file.py", true, "vscode"); + ScanResult scanResult = wrapper.ScanAsca("src/test/resources/python-vul-file.py", true, "vscode", null); // Assertions for the scan result Assertions.assertNotNull(scanResult.getRequestId(), "Request ID should not be null"); @@ -46,7 +46,7 @@ void testScanAsca_WhenFileWithVulnerabilitiesIsSentWithAgent_ReturnSuccessfulRes @Test void testScanAsca_WhenFileWithoutVulnerabilitiesIsSent_ReturnSuccessfulResponseWithCorrectValues() throws Exception { - ScanResult scanResult = wrapper.ScanAsca("src/test/resources/csharp-no-vul.cs", true, null); + ScanResult scanResult = wrapper.ScanAsca("src/test/resources/csharp-no-vul.cs", true, null, null); Assertions.assertNotNull(scanResult.getRequestId()); Assertions.assertTrue(scanResult.isStatus()); Assertions.assertNull(scanResult.getError()); @@ -55,12 +55,25 @@ void testScanAsca_WhenFileWithoutVulnerabilitiesIsSent_ReturnSuccessfulResponseW @Test void testScanAsca_WhenMissingFileExtension_ReturnFileExtensionIsRequiredFailure() throws Exception { - ScanResult scanResult = wrapper.ScanAsca("CODEOWNERS", true, null); + ScanResult scanResult = wrapper.ScanAsca("CODEOWNERS", true, null, null); Assertions.assertNotNull(scanResult.getRequestId()); Assertions.assertNotNull(scanResult.getError()); Assertions.assertEquals("The file name must have an extension.", scanResult.getError().getDescription()); } + @Test + void testScanAsca_WithIgnoreFilePath_ShouldWorkCorrectly() throws Exception { + String ignoreFile = "src/test/resources/ignored-packages.json"; + + // Test with ignore file - should not break the scanning process + ScanResult scanResult = wrapper.ScanAsca("src/test/resources/python-vul-file.py", true, "test-agent", ignoreFile); + + // Verify the scan completes successfully + Assertions.assertNotNull(scanResult.getRequestId(), "Request ID should not be null"); + Assertions.assertTrue(scanResult.isStatus(), "Status should be true"); + Assertions.assertNull(scanResult.getError(), "Error should be null when scan is successful"); + } + @Test void testScanList() throws Exception { List cxOutput = wrapper.scanList("limit=10"); diff --git a/src/test/java/com/checkmarx/ast/TenantTest.java b/src/test/java/com/checkmarx/ast/TenantTest.java index 7f49da16..91824f4e 100644 --- a/src/test/java/com/checkmarx/ast/TenantTest.java +++ b/src/test/java/com/checkmarx/ast/TenantTest.java @@ -24,4 +24,14 @@ void testAiMcpServerEnabled() throws Exception { boolean enabled = Assertions.assertDoesNotThrow(() -> wrapper.aiMcpServerEnabled()); Assertions.assertTrue(enabled, "AI MCP Server flag expected to be true"); } + + @Test + void testDevAssistEnabled() { + Assertions.assertDoesNotThrow(() -> wrapper.devAssistEnabled()); + } + + @Test + void testOneAssistEnabled() { + Assertions.assertDoesNotThrow(() -> wrapper.oneAssistEnabled()); + } } From d03675de1783da7551222129c0cd6a29c2157638 Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Wed, 21 Jan 2026 19:37:25 +0530 Subject: [PATCH 39/42] updated latest CLI version artifact. (#458) --- README.md | 2 +- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 695249a3..d302f996 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

- Logo + Logo

AST-CLI-JAVA-WRAPPER

diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index f9909fd8..5bd22e20 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2972512d55630f04f494fdf3543a3edf37906b970f5e29f58127ad27c40b652c -size 81023160 +oid sha256:a2ec1fcc76f04596c976b5039ff8d755f3e6534f06ecf442cb8d22c4f3e8f9c8 +size 81055928 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index f17f02d5..fe820c8d 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba3e45134be18e2093521df1f5e337c749e231fc926d5928815be4bbc68c4dd0 +oid sha256:23dbe8b789c4c358023a98c15fdc57a468fff934804bbbfbb3ec5fa90d803c11 size 77332664 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 52f3f40f..5423173f 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7da05ed86e02142c414ebfa2ed335b71357f7d407291b9952bf5860c7bf78dab -size 162975392 +oid sha256:a0a89e14ad8516e093625d3eff5713c83696d12494664c338839731f8dd8a79e +size 163042800 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 0341df07..a71d0477 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5fb41bc7c8d5b3db18f4626d9523fc626fd19c6f88e1bb078184e7b6e2532fed -size 82995136 +oid sha256:3f73d920a720bd8c3a6f4f234a77589e51611f07645c53baf1650396f77ed4f3 +size 83032512 From edf04ef4e36eff0c89089c87dfd8228a830a01e1 Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Thu, 5 Feb 2026 14:00:52 +0530 Subject: [PATCH 40/42] Update checkmarx-ast-cli binaries with 2.3.44 (#461) * Track Checkmarx CLI binaries with Git LFS * Update checkmarx-ast-cli to 2.3.44 --------- Co-authored-by: github-actions --- checkmarx-ast-cli.version | 2 +- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 4 ++-- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index fcf4e515..9f56377c 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.43 +2.3.44 diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 5bd22e20..45b5e94a 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2ec1fcc76f04596c976b5039ff8d755f3e6534f06ecf442cb8d22c4f3e8f9c8 -size 81055928 +oid sha256:0d4fb757538955c9f03b442698f5d0eb8bf2c1e2929c80a390ee8b4d8b50b1a7 +size 81084600 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index fe820c8d..5caaf774 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:23dbe8b789c4c358023a98c15fdc57a468fff934804bbbfbb3ec5fa90d803c11 -size 77332664 +oid sha256:21e6f82b4ff43975385902eec3f37bd724316a96cef4354b7a397667698f4fa3 +size 77398200 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 5423173f..0201cf8d 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0a89e14ad8516e093625d3eff5713c83696d12494664c338839731f8dd8a79e -size 163042800 +oid sha256:1f2c1ddf46dbdd2df9c8ecb4ef89e737ea5037379cdb18862bbdbbe365eed1f8 +size 163091056 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index a71d0477..10b897b4 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f73d920a720bd8c3a6f4f234a77589e51611f07645c53baf1650396f77ed4f3 -size 83032512 +oid sha256:d1bed011ccbb22466be3b6747f3fb2e4005be197718e8b9d9489c686645fecbc +size 83044800 From 14ef3adcaeb7f609c28db707c8033793de5440f5 Mon Sep 17 00:00:00 2001 From: Amol Mane <22643905+cx-amol-mane@users.noreply.github.com> Date: Fri, 6 Feb 2026 14:26:39 +0530 Subject: [PATCH 41/42] Add macOS Docker and Podman fallback paths to CxWrapper (#459) * Add macOS Docker and Podman fallback paths to CxWrapper * Refactor error handling for container engine accessibility in CxWrapper --- .../checkmarx/ast/wrapper/CxConstants.java | 10 ++ .../com/checkmarx/ast/wrapper/CxWrapper.java | 113 +++++++++++++++--- 2 files changed, 106 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java index 26a11dd6..ea2205ba 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxConstants.java @@ -97,4 +97,14 @@ public final class CxConstants { static final String PODMAN = "podman"; static final String PODMAN_FALLBACK_PATH = "/usr/local/bin/podman"; static final String DOCKER_FALLBACK_PATH = "/usr/local/bin/docker"; + + // Additional Docker fallback paths for macOS + // These paths cover various Docker installation methods on macOS: + // - Homebrew on Apple Silicon: /opt/homebrew/bin/docker + // - Docker Desktop CLI tools: ~/.docker/bin/docker (resolved at runtime) + // - Docker.app bundle: /Applications/Docker.app/Contents/Resources/bin/docker + // - Rancher Desktop: ~/.rd/bin/docker (resolved at runtime) + static final String DOCKER_HOMEBREW_PATH = "/opt/homebrew/bin/docker"; + static final String DOCKER_APP_PATH = "/Applications/Docker.app/Contents/Resources/bin/docker"; + static final String PODMAN_HOMEBREW_PATH = "/opt/homebrew/bin/podman"; } diff --git a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java index 1526d2b8..9e3c05f1 100644 --- a/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java +++ b/src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java @@ -421,33 +421,112 @@ public String checkEngineExist(@NonNull String engineName) throws CxException, I } private String verifyEngineOnMAC(String engineName,Listarguments) throws CxException, IOException, InterruptedException { - Exception lastException = null; - String enginePath; + this.logger.debug("Verifying container engine '{}' on macOS", engineName); + + // First, try to find the engine via shell command (works when launched from terminal) try{ - enginePath= Execution.executeCommand((arguments), logger, line->line); - return enginePath; + String enginePath = Execution.executeCommand((arguments), logger, line->line); + if (enginePath != null && !enginePath.isEmpty()) { + this.logger.debug("Found engine '{}' via shell command: {}", engineName, enginePath); + return enginePath; + } } catch (CxException | IOException e) { - lastException = e; + this.logger.debug("Shell command lookup failed for '{}': {}", engineName, e.getMessage()); } - Path dockerPath = Paths.get(CxConstants.DOCKER_FALLBACK_PATH); - Path podmanPath = Paths.get(CxConstants.PODMAN_FALLBACK_PATH); + + // Build list of fallback paths based on engine type + // This handles the case when IntelliJ is launched via GUI (double-click) and doesn't inherit shell PATH + List fallbackPaths = new ArrayList<>(); if (CxConstants.DOCKER.equalsIgnoreCase(engineName)) { - if (Files.isSymbolicLink(dockerPath)) { - return Files.readSymbolicLink(dockerPath).toAbsolutePath().toString(); + fallbackPaths.add(CxConstants.DOCKER_FALLBACK_PATH); // /usr/local/bin/docker + fallbackPaths.add(CxConstants.DOCKER_HOMEBREW_PATH); // /opt/homebrew/bin/docker (Apple Silicon) + fallbackPaths.add(CxConstants.DOCKER_APP_PATH); // /Applications/Docker.app/Contents/Resources/bin/docker + // Add user home-based paths + String userHome = System.getProperty("user.home"); + if (userHome != null) { + fallbackPaths.add(userHome + "/.docker/bin/docker"); // Docker Desktop CLI + fallbackPaths.add(userHome + "/.rd/bin/docker"); // Rancher Desktop + } + } else if (CxConstants.PODMAN.equalsIgnoreCase(engineName)) { + fallbackPaths.add(CxConstants.PODMAN_FALLBACK_PATH); // /usr/local/bin/podman + fallbackPaths.add(CxConstants.PODMAN_HOMEBREW_PATH); // /opt/homebrew/bin/podman (Apple Silicon) + // Add user home-based paths + String userHome = System.getProperty("user.home"); + if (userHome != null) { + fallbackPaths.add(userHome + "/.local/bin/podman"); } - else { return dockerPath.toAbsolutePath().toString(); } } - else if (CxConstants.PODMAN.equalsIgnoreCase(engineName)) { - if (Files.exists(podmanPath)) { - if (Files.isSymbolicLink(podmanPath)) { - return Files.readSymbolicLink(podmanPath).toAbsolutePath().toString(); + + this.logger.debug("Checking {} fallback paths for engine '{}'", fallbackPaths.size(), engineName); + + // Try each fallback path + for (String pathStr : fallbackPaths) { + Path path = Paths.get(pathStr); + this.logger.debug("Checking fallback path: {}", pathStr); + + if (Files.exists(path)) { + String resolvedPath; + try { + if (Files.isSymbolicLink(path)) { + resolvedPath = Files.readSymbolicLink(path).toAbsolutePath().toString(); + this.logger.debug("Resolved symlink {} -> {}", pathStr, resolvedPath); + } else { + resolvedPath = path.toAbsolutePath().toString(); + } + + // Verify the engine is executable and works + if (verifyEngineExecutable(resolvedPath)) { + this.logger.info("Found working container engine '{}' at: {}", engineName, resolvedPath); + return resolvedPath; + } + } catch (IOException e) { + this.logger.debug("Failed to resolve path {}: {}", pathStr, e.getMessage()); } - else{ - return podmanPath.toAbsolutePath().toString(); + } else { + this.logger.debug("Path does not exist: {}", pathStr); + } + } + + throw new CxException( + 1, engineName + " is not installed or is not accessible from the system PATH." + ); + } + + /** + * Verifies that the engine at the given path is executable and responds to --version. + * + * @param enginePath the absolute path to the container engine executable + * @return true if the engine is working, false otherwise + */ + private boolean verifyEngineExecutable(String enginePath) { + try { + Path path = Paths.get(enginePath); + if (!Files.exists(path) || !Files.isExecutable(path)) { + this.logger.debug("Engine path '{}' is not executable", enginePath); + return false; + } + + // Run a quick version check to verify the engine works + ProcessBuilder pb = new ProcessBuilder(enginePath, "--version"); + pb.redirectErrorStream(true); + Process process = pb.start(); + boolean completed = process.waitFor(5, java.util.concurrent.TimeUnit.SECONDS); + + if (completed && process.exitValue() == 0) { + this.logger.debug("Engine at '{}' verified successfully", enginePath); + return true; + } else { + this.logger.debug("Engine at '{}' failed verification (exit code: {}, completed: {})", + enginePath, process.exitValue(), completed); + if (!completed) { + process.destroyForcibly(); } + return false; } + } catch (Exception e) { + this.logger.debug("Engine verification failed for '{}': {}", enginePath, e.getMessage()); + return false; } - throw new CxException( 1, "Engine '" + engineName + "' is not installed or not symlinked to /usr/local/bin." ); } private String checkEngine(String engineName, String osType ) throws CxException, IOException, InterruptedException { From 56cb09c3094c7fc292ef2266e52bb16f2fe7b25c Mon Sep 17 00:00:00 2001 From: Anurag Dalke Date: Fri, 13 Feb 2026 19:28:39 +0530 Subject: [PATCH 42/42] Update checkmarx-ast-cli binaries with 2.3.45 (#462) * Track Checkmarx CLI binaries with Git LFS * Update checkmarx-ast-cli to 2.3.45 --------- Co-authored-by: github-actions --- checkmarx-ast-cli.version | 2 +- src/main/resources/cx-linux | 4 ++-- src/main/resources/cx-linux-arm | 2 +- src/main/resources/cx-mac | 4 ++-- src/main/resources/cx.exe | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version index 9f56377c..a5774236 100644 --- a/checkmarx-ast-cli.version +++ b/checkmarx-ast-cli.version @@ -1 +1 @@ -2.3.44 +2.3.45 diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux index 45b5e94a..c8b2d1e6 100755 --- a/src/main/resources/cx-linux +++ b/src/main/resources/cx-linux @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d4fb757538955c9f03b442698f5d0eb8bf2c1e2929c80a390ee8b4d8b50b1a7 -size 81084600 +oid sha256:18b7c2808d4513ba9ed1041c48eba1da4ced2f644cd03f223790dadc0739b3b4 +size 81105080 diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm index 5caaf774..cd70ab03 100755 --- a/src/main/resources/cx-linux-arm +++ b/src/main/resources/cx-linux-arm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21e6f82b4ff43975385902eec3f37bd724316a96cef4354b7a397667698f4fa3 +oid sha256:f24c5b06bf7705376d34420443f3e05dfdd1e5da78cdbff451fec93a686f1f31 size 77398200 diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac index 0201cf8d..6ca3efbe 100755 --- a/src/main/resources/cx-mac +++ b/src/main/resources/cx-mac @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f2c1ddf46dbdd2df9c8ecb4ef89e737ea5037379cdb18862bbdbbe365eed1f8 -size 163091056 +oid sha256:886568c8a6d83b8a56d6a875fa8b356fd3cb5a4902e9023b0c68ba25d87e00bb +size 163157360 diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe index 10b897b4..6eea9b98 100644 --- a/src/main/resources/cx.exe +++ b/src/main/resources/cx.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d1bed011ccbb22466be3b6747f3fb2e4005be197718e8b9d9489c686645fecbc -size 83044800 +oid sha256:95de44ce585c74602f12e129f67b7a0c9c9b789d469f9338e655d5f2fa069f28 +size 83068864