9

I am wanting to use the gl-sast-report.json file created during the SAST process in a subsequent stage of my CI but it is not found.

ci.yml

include:
  - template: Security/SAST.gitlab-ci.yml

stages:
  - test
  - .post
sast:
  rules:
    - if: $CI_COMMIT_TAG

send-reports:
  stage: .post
  dependencies: 
    - sast
  script: 
    - ls
    - echo "in post stage"
    - cat gl-sast-report.json

output:

Running with gitlab-runner 13.2.1 (efa30e33)
on blah blah blah
Preparing the "docker" executor
00:01
.
.
.

Preparing environment
00:01
Running on runner-zqk9bcef-project-4296-concurrent-0 via ff93ba7b6ee2...
Getting source from Git repository
00:01
Fetching changes with git depth set to 50...
Reinitialized existing Git repository in blah blah
Checking out 9c2edf67 as 39-test-dso...
Removing gl-sast-report.json
Skipping Git submodules setup
Executing "step_script" stage of the job script
00:03
$ ls
<stuff in the repo>
$ echo "in .post stage"
in post stage
$ cat gl-sast-report.json
cat: can't open 'gl-sast-report.json': No such file or directory
ERROR: Job failed: exit code 1

You can see the line Removing gl-sast-report.json which I assume is the issue.

I don't see that anywhere in the SAST.gitlab-ci.yml at https://gitlab.com/gitlab-org/gitlab/-/blob/v11.11.0-rc2-ee/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml#L33-45

Any ideas on how to use this artifact in the next stage of my CI pipeline?

UPDATE:

So I tried out k33g_org's suggestion below but to no avail. Seems that this is due to limitations in the sast template specifically. Did the following test.

include:
  - template: Security/SAST.gitlab-ci.yml

stages:
  - test
  - upload

something:
  stage: test
  script:
      - echo "in something"
      - echo "this is something" > something.txt
  artifacts:
      paths: [something.txt]

sast:
  before_script:
      - echo "hello from before sast"
      - echo "this is in the file" > test.txt
  artifacts:
    reports:
      sast: gl-sast-report.json
    paths: [gl-sast-report.json, test.txt]

send-reports:
  stage: upload
  dependencies:
    - sast
    - something
  before_script:
      - echo "This is the send-reports before_script"
  script:
    - echo "in send-reports job"
    - ls
  artifacts:
      reports:
          sast: gl-sast-report.json

Three changes:

  1. Updated code with k33g_org's suggestion
  2. Created another artifact in the sast job (to see if it would pass through to send-reports job)
  3. Created a new job (something) where I created a new something.txt artifact (to see if it would pass through to send-reports job)

Output:

Preparing environment
00:01
Running on runner-zqx7qoq-project-4296-concurrent-0 via e3fe672984b4...
Getting source from Git repository
Fetching changes with git depth set to 50...
Reinitialized existing Git repository in /<repo>
Checking out 26501c44 as <branch_name>...
Removing something.txt
Skipping Git submodules setup
Downloading artifacts
00:00
Downloading artifacts for something (64950)...
Downloading artifacts from coordinator... ok        id=64950 
responseStatus=200 OK token=zoJwysdq
Executing "step_script" stage of the job script
00:01
$ echo "This is the send-reports before_script"
This is the send-reports before_script
$ echo "in send-reports job"
in send-reports job
$ ls
...<other stuff in repo>
something.txt
Uploading artifacts for successful job
00:01
Uploading artifacts...
WARNING: gl-sast-report.json: no matching files    
ERROR: No files to upload                          
Cleaning up file based variables
00:01
Job succeeded

Notes:

  • something.txt made it to this job
  • all artifacts from the sast job to not make it to subsequent jobs

I can only conclude that there is something internal to the sast template that is not allowing artifacts to propagate to subsequent jobs.

Archie Archbold
  • 179
  • 1
  • 2
  • 8

4 Answers4

7

I spent a full day banging my head against this, trying to access the gl-sast-report.json file generated by the built-in IaC scanner. Here's what ultimately worked for me:

First and foremost, DO NOT use this code suggested by GitLab's documentation:

include:
  - template: Security/SAST-IaC.latest.gitlab-ci.yml

The above code works fine if all you want to do is scan for IaC vulnerabilities and download the report from the GitLab UI later. But who wants to do that?! I want to access the report in my next job and fail the pipeline if there are medium+ vulnerabilities in the report!

If that's what you want to do, you'll need to add all of the code from the official GitLab IaC scanner template to your pipeline, and then make some modifications. You can find the latest template code here, or use my example below.

Modified template:

# Read more about this feature here: https://docs.gitlab.com/ee/user/application_security/iac_scanning/
#
# Configure SAST with CI/CD variables (https://docs.gitlab.com/ee/ci/variables/index.html).
# List of available variables: https://docs.gitlab.com/ee/user/application_security/iac_scanning/index.html

variables:
  # Setting this variable will affect all Security templates
  # (SAST, Dependency Scanning, ...)
  TEMPLATE_REGISTRY_HOST: 'registry.gitlab.com'
  SECURE_ANALYZERS_PREFIX: "$TEMPLATE_REGISTRY_HOST/security-products"
  SAST_IMAGE_SUFFIX: ""

  SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"

iac-sast:
  stage: test
  artifacts:
    name: sast
    paths:
      - gl-sast-report.json
    #reports:
    #  sast: gl-sast-report.json
    when: always
  rules:
    - when: never
  # `rules` must be overridden explicitly by each child job
  # see https://gitlab.com/gitlab-org/gitlab/-/issues/218444
  variables:
    SEARCH_MAX_DEPTH: 4
  allow_failure: true
  script:
    - /analyzer run

kics-iac-sast:
  extends: iac-sast
  image:
    name: "$SAST_ANALYZER_IMAGE"
  variables:
    SAST_ANALYZER_IMAGE_TAG: 3
    SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/kics:$SAST_ANALYZER_IMAGE_TAG$SAST_IMAGE_SUFFIX"
  rules:
    - if: $SAST_DISABLED
      when: never
    - if: $SAST_EXCLUDED_ANALYZERS =~ /kics/
      when: never
    - if: $CI_COMMIT_BRANCH
  

Enforce Compliance:
  stage: Compliance
  before_script:
    - apk add jq
  script:
    - jq -r '.vulnerabilities[] | select(.severity == "Critical") | (.severity, .message, .location, .identifiers[].url)' gl-sast-report.json > results.txt
    - jq -r '.vulnerabilities[] | select(.severity == "High") | (.severity, .message, .location, .identifiers[].url)' gl-sast-report.json >> results.txt
    - jq -r '.vulnerabilities[] | select(.severity == "Medium") | (.severity, .message, .location, .identifiers[].url)' gl-sast-report.json >> results.txt
    - chmod u+x check-sast-results.sh
    - ./check-sast-results.sh

You'll also need to make sure to add two stages to your pipeline (if you don't have them already):

stages:
  # add these to whatever other stages you already have
  - test
  - Compliance

Note: it's extremely important that your job which is trying to access gl-sast-report.json ("Compliance" in this case) is not in the same stage as the sast scans themselves ("test" in this case). If they are, then your job will try to access the report before it exists and fail.

I'll include my shell script referenced in the pipeline in case you want to use that too:

#!/bin/sh

if [ -s results.txt ]; then
        echo ""
        echo ""
        cat results.txt
        echo ""
        echo "ERROR: SAST SCAN FOUND VULNERABILITIES - FIX ALL VULNERABILITIES TO CONTINUE"
        echo ""
        exit 1
fi

This is a basic script that checks to see if the "results.txt" file has any contents. If it does, it exits with code 1 to break the pipeline and print the vulnerabilities. If there are no contents in the file, the script exits with code 0 and the pipeline continues (allowing you to deploy your infra). Save the file above as "check-sast-results.sh" in the root directory of your GitLab repository (the same level where ".gitlab-ci.yml" resides).

Hope this helps someone out there.

A. Kendall
  • 391
  • 3
  • 12
  • 1
    Nice, in addition, using this GitLab report Parser: https://github.com/pcfens/sast-parser in the Compliance step to parse and generate an HTML artifact. – Khalil Gharbaoui Oct 12 '22 at 09:48
3

in the first job (sast) add this:

  artifacts:
    paths: [gl-sast-report.json]
    reports:
      sast: gl-sast-report.json

and in the next job (send-reports) add this

  artifacts:
    reports:
      sast: gl-sast-report.json

Then you should be able to access the report in the next job (send-reports)

k33g_org
  • 530
  • 5
  • 8
  • Thank you. Tried your suggestion but no joy. Output added to original question above. – Archie Archbold Oct 29 '20 at 16:31
  • 1
    @ArchieArchbold I think that `gl-sast-report.json` is not generated when the first stage if there is no vulnerability. It works in my case https://gitlab.com/make-ci-lovable/sandbox/hello/-/jobs/821152056 the ci script is here: https://gitlab.com/make-ci-lovable/sandbox/hello/-/blob/master/.gitlab-ci.yml – k33g_org Oct 30 '20 at 11:07
  • **But** you could have some issues with the MR because of the detached pipeline. The only workaround I found is to override the SAST jobs I need https://gitlab.com/make-ci-lovable/sandbox/hello/-/blob/k33g-master-patch-62763/.gitlab-ci.yml#L24 – k33g_org Oct 30 '20 at 12:46
2

Instead of referencing the gl-sast-report.json artifact as sast report, reference it as a regular artifact.

So what you should do is declare the artifact this way

artifacts:
  paths:
    - 'gl-sast-report.json'

instead of

reports:
  sast: gl-sast-report.json
0

I've found this issue too, also impacts some of the other scanners; I raised an issue with GitLab to fix:

https://gitlab.com/gitlab-org/gitlab/-/issues/345696

  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/30346097) – tdy Nov 16 '21 at 03:35