gitlab-cisastsemgrep

Why is GitLab CI SAST not exluding directories that I ask it to exclude?


I have enabled SAST scanning in GitLab CI (GitLab Community Edition) 14.5.2. The SAST runs tools like semgrep and ESLint run over the source code and scan for vulnerabilities. This works... except it's not excluding paths and files from the results that I tell it to so my reports are filled with junk from 3rd party libs.

Since I don't want test code or 3rd party stuff in the report I use the GitLab provided variable for this purpose called SAST_EXCLUDED_PATHS that I use to exclude some dirs. My value is like this:

    variables:
        SAST_EXCLUDED_PATHS: spec, test, tests, tmp, server/libs, assets, vendor, *.min.js

So basically in addition to the default paths I've told it not to scan server/libs, assets, vendor or *.min.js.

So the simplified .gitlab-ci.yml that adds the step, adds the exclusions and also sets SECURE_LOG_LEVEL to "debug". The latter so I can see the debug output of stages such as sast-semgrep.

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

stages:
    - test

# Run a SAST scan & report on the sources
sast:
    stage: test
    variables:
        SAST_EXCLUDED_PATHS: spec, test, tests, tmp, server/libs, assets, vendor, *.min.js
        SECURE_LOG_LEVEL: "debug"

I can see from the debug that sast-semgrep is taking my exclusions and turning them into --exclude arguments. But it just scans the paths anyway. I have even tried appending glob rules onto the paths, e.g. "server/libs/**". I have even tried using absolute paths e.g. "$CI_PROJECT_DIR/server/libs" but that doesn't work either.

I have enabled debug console output and I can even see tools like semgrep are correctly expanding out the exclusions. But it doesn't work! This example includes a $CI_PROJECT_DIR expansion that doesn't make any difference.

[DEBU] [Semgrep] [2022-01-26T20:59:40Z] ▶ /usr/local/bin/semgrep -f /rules -o /builds/myprj/myprj/semgrep.sarif --sarif --no-rewrite-rule-ids --strict --disable-version-check --no-git-ignore --exclude spec --exclude  test --exclude  tests --exclude  tmp --exclude  "/builds/myprj/myprj/server/libs" --exclude  assets --exclude  vendor --exclude  *.min.js --enable-metrics /builds/myprj/myprj
[DEBU] [Semgrep] [2022-01-26T21:01:34Z] ▶ METRICS: Using configs from the Registry (like --config=p/ci) reports pseudonymous rule metrics to semgrep.dev.
To disable Registry rule metrics, use "--metrics=off".
Using configs only from local files (like --config=xyz.yml) does not enable metrics.
More information: https://semgrep.dev/docs/metrics
excluding files:
- spec
-  test
-  tests
-  tmp
-  "/builds/myprj/myprj/server/libs"
-  assets
-  vendor
-  *.min.js

As far as I can tell I'm using the latest GitLab and docker images that Gitlab invokes. Does anyone know why exclusion isn't working? Am I missing something obvious. FYI I have also tried the same CI/CD script in GitLab Ultimate evaluation copy and its the same deal. So it's not to do with the less powerful SAST functionality in the Community Edition which should still produce a JSON report. Any ideas?


Solution

  • Hope I'm not too late. I've encountered the same problem and what resolved it for me was to delete the space between the excluded paths. Your SAST_EXCLUDED_PATHS variable should look like this:

      variables:
            SAST_EXCLUDED_PATHS: spec,test,tests,tmp,server/libs,assets,vendor,*.min.js