From 3442438816e3f8b83f1a7d17ffce08be67267e37 Mon Sep 17 00:00:00 2001 From: Kirill Efimov Date: Mon, 30 Oct 2023 13:35:44 +0100 Subject: [PATCH 1/5] Add pipelines for all supported SAST providers --- .github/scripts/fortify-wait-fpr.js | 63 ++++++++++++++++++++++ .github/workflows/codeql.yml | 45 ++++++++++++++++ .github/workflows/cx.yml | 36 +++++++++++++ .github/workflows/fortify.yml | 68 ++++++++++++++++++++++++ .github/workflows/{main.yml => snyk.yml} | 18 ++++--- pom.xml | 38 +++++++++++++ src/main/java/SQLInjectionExample.java | 26 +++++---- 7 files changed, 278 insertions(+), 16 deletions(-) create mode 100644 .github/scripts/fortify-wait-fpr.js create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/cx.yml create mode 100644 .github/workflows/fortify.yml rename .github/workflows/{main.yml => snyk.yml} (62%) create mode 100644 pom.xml diff --git a/.github/scripts/fortify-wait-fpr.js b/.github/scripts/fortify-wait-fpr.js new file mode 100644 index 0000000..47b761c --- /dev/null +++ b/.github/scripts/fortify-wait-fpr.js @@ -0,0 +1,63 @@ +const fs = require('node:fs'); +const timers = require('node:timers/promises'); + +const scanId = process.argv[2]; +const FORTIFY_USER = process.env.FORTIFY_USER; +const FORTIFY_TOKEN = process.env.FORTIFY_TOKEN; +const FORTIFY_TENANT = process.env.FORTIFY_TENANT; + +async function main() { + const tokenData = await fetch('https://api.ams.fortify.com/oauth/token', { + method: 'POST', + headers: {'content-type': 'application/x-www-form-urlencoded'}, + body: `grant_type=password&scope=api-tenant&username=${FORTIFY_TENANT}\\${FORTIFY_USER}&password=${FORTIFY_TOKEN}&security_code=` + }).then(r => r.json()); + + if (!tokenData || !tokenData.access_token) { + throw new Error("Can't authenticate, check credentials."); + } + + const token = tokenData.access_token; + + while (true) { + const summaryResponse = await fetch(`https://api.ams.fortify.com/api/v3/scans/${scanId}/summary`, { + headers: {Authorization: `Bearer ${token}`} + }); + + if (summaryResponse.status === 200) { + const summaryData = await summaryResponse.json(); + + if (summaryData.analysisStatusType === 'Completed') { + break; + } + console.log(`Scan status: ${summaryData.analysisStatusType}...`); + } else { + console.log(`Scan API status: ${summaryResponse.status}...`); + } + await timers.setTimeout(5000); + } + + let buffer; + + while (true) { + const fileResponse = await fetch(`https://api.ams.fortify.com/api/v3/scans/${scanId}/fpr`, { + headers: {Authorization: `Bearer ${token}`} + }); + + if (fileResponse.status === 200) { + buffer = await fileResponse.arrayBuffer(); + break; + } + + if ([202, 429].includes(fileResponse.status)) { + console.log(`Waiting FRP file...`); + await timers.setTimeout(5000); + } else { + throw new Error(`Unexpected status code from fpr endpoint: ${fileResponse.status}.`); + } + } + + fs.writeFileSync('./scandata.fpr', Buffer.from(buffer)); +} + +main().catch(console.error); diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..b536709 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,45 @@ +on: [pull_request] + +permissions: + contents: read + checks: write + actions: write + statuses: write + +jobs: + test_codeql: + runs-on: ubuntu-latest + steps: + - name: Setup Java on this machine + uses: actions/setup-java@v3 + with: + distribution: "oracle" + java-version: "19" + - name: Setup Maven on this machine + uses: stCarolas/setup-maven@v4.5 + with: + maven-version: 3.8.6 + + - name: Checkout repo to get code + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: java + + - name: Run CodeQL autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Run CodeQL SAST scan + uses: github/codeql-action/analyze@v2 + with: + output: ../results + + - name: Run Mobb on the findings and get fixes + if: always() + uses: mobb-dev/action@v1 + with: + report-file: ../results/java.sarif + api-key: ${{ secrets.MOBB_API_TOKEN }} + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/cx.yml b/.github/workflows/cx.yml new file mode 100644 index 0000000..5546b73 --- /dev/null +++ b/.github/workflows/cx.yml @@ -0,0 +1,36 @@ +on: [pull_request] + +permissions: + contents: read + checks: write + actions: write + statuses: write + +jobs: + test_cx: + runs-on: ubuntu-latest + steps: + - name: Download and configure Checkmarx CLI + run: | + mkdir -p /tmp/cx + cd /tmp/cx + wget https://github.com/Checkmarx/ast-cli/releases/download/2.0.54/ast-cli_2.0.54_linux_x64.tar.gz -O checkmarx.tar.gz + tar -xf checkmarx.tar.gz + ./cx configure set --prop-name cx_apikey --prop-value ${{ secrets.CX_API_KEY }} + ./cx configure set --prop-name cx_base_auth_uri --prop-value ${{ secrets.CX_BASE_AUTH_URI }} + ./cx configure set --prop-name cx_base_uri --prop-value ${{ secrets.CX_BASE_URI }} + ./cx configure set --prop-name cx_tenant --prop-value ${{ secrets.CX_TENANT }} + + - name: Checkout repo to get code + uses: actions/checkout@v3 + + - name: Run Cx SAST scan + run: /tmp/cx/cx scan create --project-name my-test-project -s ./ --file-filter '!.github' --report-format json --scan-types sast --branch nobranch + + - name: Run Mobb on the findings and get fixes + if: always() + uses: mobb-dev/action@v1 + with: + report-file: "cx_result.json" + api-key: ${{ secrets.MOBB_API_TOKEN }} + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/fortify.yml b/.github/workflows/fortify.yml new file mode 100644 index 0000000..778f94d --- /dev/null +++ b/.github/workflows/fortify.yml @@ -0,0 +1,68 @@ +on: [pull_request] + +permissions: + contents: read + checks: write + actions: write + statuses: write + +jobs: + test_fortify: + runs-on: ubuntu-latest + steps: + - name: Setup Java on this machine + uses: actions/setup-java@v3 + with: + distribution: "oracle" + java-version: "19" + - name: Setup Maven on this machine + uses: stCarolas/setup-maven@v4.5 + with: + maven-version: 3.8.6 + - name: Setup Node on this machine + uses: actions/setup-node@v3.6.0 + with: + node-version: 18 + - name: Install sed + run: sudo apt-get update && sudo apt-get install -y sed + + - name: Checkout repo to get code + uses: actions/checkout@v3 + + - name: Download Fortify uploader CLI + run: | + wget https://tools.fortify.com/scancentral/Fortify_ScanCentral_Client_21.2.0_x64.zip -O fcs.zip + unzip fcs.zip + chmod +x bin/scancentral + wget https://github.com/fod-dev/fod-uploader-java/releases/download/v5.4.0/FodUpload.jar -O FodUpload.jar + + - name: Run Fortify SAST scan + run: | + ./bin/scancentral package -bt mvn -o fortify_package.zip + + UPLOAD_OUTPUT=$(java -jar FodUpload.jar \ + -z fortify_package.zip \ + -ep SingleScanOnly \ + -portalurl https://ams.fortify.com/ \ + -apiurl https://api.ams.fortify.com/ \ + -userCredentials ${{ secrets.FORTIFY_USER }} ${{ secrets.FORTIFY_TOKEN }} \ + -tenantCode ${{ secrets.FORTIFY_TENANT }} \ + -releaseId ${{ secrets.FORTIFY_RELEASE_ID }} \ + -pp Queue) + SCAN_ID=$(echo "$UPLOAD_OUTPUT" | sed -n 's/Scan \([0-9]*\).*$/\1/p') + + FORTIFY_USER=${{ secrets.FORTIFY_USER }} FORTIFY_TOKEN=${{ secrets.FORTIFY_TOKEN }} FORTIFY_TENANT=${{ secrets.FORTIFY_TENANT }} node .github/scripts/fortify-wait-fpr.js "$SCAN_ID" + - name: Archive fpr + if: always() + uses: actions/upload-artifact@v3 + with: + name: fpr + path: scandata.fpr + + - name: Run Mobb on the findings and get fixes + if: always() + uses: mobb-dev/action@v1 + with: + report-file: "scandata.fpr" + api-key: ${{ secrets.MOBB_API_TOKEN }} + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/main.yml b/.github/workflows/snyk.yml similarity index 62% rename from .github/workflows/main.yml rename to .github/workflows/snyk.yml index 5a3246f..7fbd9e4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/snyk.yml @@ -1,25 +1,29 @@ on: [pull_request] + permissions: contents: read checks: write actions: write statuses: write - jobs: - test_job: + test_snyk: runs-on: ubuntu-latest steps: + - name: Setup Node on this machine + uses: actions/setup-node@v3.6.0 + with: + node-version: 18 + - name: Checkout repo to get code uses: actions/checkout@v3 + - name: Run Snyk SAST scan run: - npx snyk auth ${{ secrets.SNYK_API_KEY }} - - npx snyk code test --sarif-file-output=/home/runner/report.json ./ - + npx snyk auth ${{ secrets.SNYK_API_KEY }} && npx snyk code test --sarif-file-output=/home/runner/report.json ./ shell: bash -l {0} - - name: Mobb action step + + - name: Run Mobb on the findings and get fixes if: failure() uses: mobb-dev/action@v1 with: diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..bc805e6 --- /dev/null +++ b/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + testgroup + testartifact + 1.0-SNAPSHOT + jar + testproj + + + true + UTF-8 + + + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + 17 + 17 + + + + + diff --git a/src/main/java/SQLInjectionExample.java b/src/main/java/SQLInjectionExample.java index 16fca15..4d50620 100644 --- a/src/main/java/SQLInjectionExample.java +++ b/src/main/java/SQLInjectionExample.java @@ -1,14 +1,22 @@ -import java.sql.*; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; -public class SQLInjectionExample { - public static void main(String[] args) throws SQLException { - String userInputA = args[1]; +public class SQLInjectionExample extends HttpServlet { + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { + try { + Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db"); - Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db"); - + String query = "SELECT * FROM users WHERE username = '" + request.getParameter("username") + "';"; + Statement stmt = con.createStatement(); - String query = "SELECT * FROM users WHERE username = '" + userInputA + "';"; - Statement stmt = con.createStatement(); - ResultSet rs = stmt.executeQuery(query); + stmt.executeQuery(query); + } catch (Exception e) { + throw new ServletException(e); + } } } From 7a8e29f6efb1642a5bb8ac9de94f14df3f9e27e7 Mon Sep 17 00:00:00 2001 From: Kirill Efimov Date: Mon, 30 Oct 2023 16:13:08 +0100 Subject: [PATCH 2/5] Fortify pipeline config --- .github/workflows/codeql.yml | 45 ------------------------------------ .github/workflows/cx.yml | 36 ----------------------------- .github/workflows/snyk.yml | 32 ------------------------- 3 files changed, 113 deletions(-) delete mode 100644 .github/workflows/codeql.yml delete mode 100644 .github/workflows/cx.yml delete mode 100644 .github/workflows/snyk.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index b536709..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,45 +0,0 @@ -on: [pull_request] - -permissions: - contents: read - checks: write - actions: write - statuses: write - -jobs: - test_codeql: - runs-on: ubuntu-latest - steps: - - name: Setup Java on this machine - uses: actions/setup-java@v3 - with: - distribution: "oracle" - java-version: "19" - - name: Setup Maven on this machine - uses: stCarolas/setup-maven@v4.5 - with: - maven-version: 3.8.6 - - - name: Checkout repo to get code - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: java - - - name: Run CodeQL autobuild - uses: github/codeql-action/autobuild@v2 - - - name: Run CodeQL SAST scan - uses: github/codeql-action/analyze@v2 - with: - output: ../results - - - name: Run Mobb on the findings and get fixes - if: always() - uses: mobb-dev/action@v1 - with: - report-file: ../results/java.sarif - api-key: ${{ secrets.MOBB_API_TOKEN }} - github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/cx.yml b/.github/workflows/cx.yml deleted file mode 100644 index 5546b73..0000000 --- a/.github/workflows/cx.yml +++ /dev/null @@ -1,36 +0,0 @@ -on: [pull_request] - -permissions: - contents: read - checks: write - actions: write - statuses: write - -jobs: - test_cx: - runs-on: ubuntu-latest - steps: - - name: Download and configure Checkmarx CLI - run: | - mkdir -p /tmp/cx - cd /tmp/cx - wget https://github.com/Checkmarx/ast-cli/releases/download/2.0.54/ast-cli_2.0.54_linux_x64.tar.gz -O checkmarx.tar.gz - tar -xf checkmarx.tar.gz - ./cx configure set --prop-name cx_apikey --prop-value ${{ secrets.CX_API_KEY }} - ./cx configure set --prop-name cx_base_auth_uri --prop-value ${{ secrets.CX_BASE_AUTH_URI }} - ./cx configure set --prop-name cx_base_uri --prop-value ${{ secrets.CX_BASE_URI }} - ./cx configure set --prop-name cx_tenant --prop-value ${{ secrets.CX_TENANT }} - - - name: Checkout repo to get code - uses: actions/checkout@v3 - - - name: Run Cx SAST scan - run: /tmp/cx/cx scan create --project-name my-test-project -s ./ --file-filter '!.github' --report-format json --scan-types sast --branch nobranch - - - name: Run Mobb on the findings and get fixes - if: always() - uses: mobb-dev/action@v1 - with: - report-file: "cx_result.json" - api-key: ${{ secrets.MOBB_API_TOKEN }} - github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/snyk.yml b/.github/workflows/snyk.yml deleted file mode 100644 index 7fbd9e4..0000000 --- a/.github/workflows/snyk.yml +++ /dev/null @@ -1,32 +0,0 @@ -on: [pull_request] - -permissions: - contents: read - checks: write - actions: write - statuses: write - -jobs: - test_snyk: - runs-on: ubuntu-latest - steps: - - name: Setup Node on this machine - uses: actions/setup-node@v3.6.0 - with: - node-version: 18 - - - name: Checkout repo to get code - uses: actions/checkout@v3 - - - name: Run Snyk SAST scan - run: - npx snyk auth ${{ secrets.SNYK_API_KEY }} && npx snyk code test --sarif-file-output=/home/runner/report.json ./ - shell: bash -l {0} - - - name: Run Mobb on the findings and get fixes - if: failure() - uses: mobb-dev/action@v1 - with: - report-file: "/home/runner/report.json" - api-key: ${{ secrets.MOBB_API_TOKEN }} - github-token: ${{ secrets.GITHUB_TOKEN }} From 44ddf5ca6714d347b8c60cac569fc1ede98a0d7e Mon Sep 17 00:00:00 2001 From: Eitan Worcel <96389636+mobbeitan@users.noreply.github.com> Date: Mon, 15 Jan 2024 16:36:50 -0500 Subject: [PATCH 3/5] Update fortify.yml --- .github/workflows/fortify.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/fortify.yml b/.github/workflows/fortify.yml index 778f94d..0132802 100644 --- a/.github/workflows/fortify.yml +++ b/.github/workflows/fortify.yml @@ -1,10 +1,10 @@ on: [pull_request] - permissions: - contents: read - checks: write - actions: write - statuses: write + actions: write + checks: write + contents: write + pull-requests: write + statuses: write jobs: test_fortify: @@ -61,8 +61,10 @@ jobs: - name: Run Mobb on the findings and get fixes if: always() - uses: mobb-dev/action@v1 + uses: mobb-dev/action@beta0.0.4 with: report-file: "scandata.fpr" api-key: ${{ secrets.MOBB_API_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} + scanner: fortify + mobb-project-name: Action From 389ad56b7c34d960c7addcbf300c33afed58ae06 Mon Sep 17 00:00:00 2001 From: Eitan Worcel <96389636+mobbeitan@users.noreply.github.com> Date: Mon, 15 Jan 2024 16:38:54 -0500 Subject: [PATCH 4/5] Update SQLInjectionExample.java --- src/main/java/SQLInjectionExample.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/SQLInjectionExample.java b/src/main/java/SQLInjectionExample.java index 4d50620..751f7b6 100644 --- a/src/main/java/SQLInjectionExample.java +++ b/src/main/java/SQLInjectionExample.java @@ -11,7 +11,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t try { Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db"); - String query = "SELECT * FROM users WHERE username = '" + request.getParameter("username") + "';"; + String query = "SELECT * FROM users WHERE username = '" + request.getParameter("username") + "';"; Statement stmt = con.createStatement(); stmt.executeQuery(query); From 2707cda43a1e9e878327219939e6c64ea7dde949 Mon Sep 17 00:00:00 2001 From: Eitan Worcel <96389636+mobbeitan@users.noreply.github.com> Date: Fri, 26 Jan 2024 13:46:47 -0500 Subject: [PATCH 5/5] Update fortify.yml --- .github/workflows/fortify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fortify.yml b/.github/workflows/fortify.yml index 0132802..9036fc7 100644 --- a/.github/workflows/fortify.yml +++ b/.github/workflows/fortify.yml @@ -61,7 +61,7 @@ jobs: - name: Run Mobb on the findings and get fixes if: always() - uses: mobb-dev/action@beta0.0.4 + uses: mobb-dev/action/review@v1.1 with: report-file: "scandata.fpr" api-key: ${{ secrets.MOBB_API_TOKEN }}