Home Technical Support Static Analysis Tools Overview: Bandit, Bundler‑Audit, FindSecBugs & AuditJS

Static Analysis Tools Overview: Bandit, Bundler‑Audit, FindSecBugs & AuditJS

Last updated on Jan 06, 2026

Static Analysis Tools Overview: Bandit, Bundler‑Audit, FindSecBugs & AuditJS

Static application security testing (SAST) is a cornerstone of any DevSecOps pipeline. In the Practical DevSecOps training you’ll encounter four widely‑used open‑source scanners: Bandit, Bundler‑Audit, FindSecBugs, and AuditJS. This article explains why some tools require extra prerequisites, how to handle false‑positives, filter results by severity, improve scan commands, and troubleshoot common errors such as exit‑code handling and ignore‑file formatting.


1. Bundler‑Audit – Why Ruby Is Needed on Your Local Machine but Not in GitLab

1.1 Installation methods matter

Method How it works When you need Ruby Typical use case
Docker (GitLab CI) The tool runs inside a pre‑built container that already contains Ruby, Bundler, and the bundler-audit gem. No – the container isolates the runtime. Fast, reproducible CI pipelines; no host‑level dependencies.
Native (local or self‑hosted CI) You install the gem directly with gem install bundler-audit. Yes – the host must have a compatible Ruby interpreter and the gem command. Quick local testing, custom environments, or when Docker is not an option.

1.2 Practical tip

  • CI/CD (GitLab/GitHub): Use the official Docker image ruby:2.7-bundler-audit (or a custom image) and invoke bundler-audit inside the job script.
  • Local development: Install Ruby (via rbenv, rvm, or your package manager) then run gem install bundler-audit.

By leveraging Docker, the pipeline avoids “Ruby not found” errors and guarantees the same version of the scanner across all runs.


2. Bandit – Handling False Positives in the Baseline File

2.1 What is a baseline file?

A baseline (.bandit-baseline.json) stores findings from a previous scan. During a new scan, Bandit compares current results against the baseline and flags any new issues.

2.2 Why your changes seem ignored

  • All baseline entries are still displayed – Bandit shows every issue that exists in the baseline, regardless of whether you edited the source file.
  • Only one entry needs to be marked as false‑positive – As soon as a single issue in the baseline is flagged with "false_positive": true, the overall scan will display a green tick.

2.3 Step‑by‑step fix

  1. Open the baseline snippet: https://gitlab.practical-devsecops.training/-/snippets/15.
  2. Locate the issue you want to suppress and set "false_positive": true.
  3. Commit the updated baseline file.
  4. Re‑run bandit -r . -c .bandit-baseline.json.

Now the scan will treat that entry as ignored, and the pipeline will pass.


3. Bandit – Failing a Build Only on High‑Severity Findings

Bandit provides a simple flag to limit the exit status to a chosen severity level.

# Fail the job only when HIGH or CRITICAL issues are found
bandit -r . -lll   # -lll = low, low, low → only high & above trigger non‑zero exit
Flag Meaning
-l Show low severity only (does not affect exit code).
-ll Show low + medium.
-lll Show low + medium + high (default).
-x Exclude files or directories.

You can also combine with --exit-zero to always succeed and rely on a separate script to parse the JSON output for high‑severity findings.


4. FindSecBugs – Aligning the Scan with DevSecOps Best Practices

4.1 Current command (example)

findsecbugs -output findsecbugs-report.xml -progress -low -medium -high .

4.2 Recommendations for a production‑grade pipeline

  1. Limit output to actionable severities – Drop low‑severity findings to reduce noise.
    findsecbugs -output findsecbugs-report.xml -medium -high .
    
  2. Use a machine‑readable format – XML (or SARIF) integrates easily with CI dashboards, DefectDojo, or GitLab Security Reports.
  3. Fail the job on critical findings – Add -failOnHigh (or parse the XML after the scan).

4.3 Sample improved command

findsecbugs -output findsecbugs-report.sarif \
            -medium -high \
            -failOnHigh \
            -progress .

This command produces a SARIF file that can be uploaded to GitLab/GitHub security dashboards and aborts the pipeline if any high‑severity issue is detected.


5. AuditJS – Ignoring Specific Vulnerabilities

AuditJS reads an ignore file (auditjs-ignore.json) that must be valid JSON. A common mistake is using trailing commas or comments, which break the parser.

5.1 Correct ignore‑file structure

{
  "ignore": [
    {
      "module": "lodash",
      "version": "4.17.15",
      "reason": "Patched in downstream library"
    },
    {
      "module": "express",
      "version": "4.16.0",
      "reason": "False positive – not used in production"
    }
  ]
}

5.2 How to use it

auditjs scan . --ignore-file auditjs-ignore.json

If you still see errors, run jq . auditjs-ignore.json to validate the JSON syntax.


6. Bandit Exit Codes – Why Piping Changes the Result

  • Without piping: bandit -r . -f json returns exit code 1 when any issue (of any severity) is found.
  • With piping: bandit -r . -f json | tee bandit-output.json returns exit code 0 because the pipeline’s final command (tee) succeeds, masking Bandit’s original status.

6.1 Preserve Bandit’s exit code

bandit -r . -f json | tee bandit-output.json
# Capture Bandit’s status in $PIPESTATUS (bash)
if [ ${PIPESTATUS[0]} -ne 0 ]; then
  echo "Bandit detected vulnerabilities"
  exit 1
fi

Or use set -o pipefail at the start of the script to propagate the first non‑zero status.


7. Quick Reference & Tips

Topic Command / Tip
Run Bundler‑Audit in CI docker run --rm -v $(pwd):/app -w /app ruby:2.7 bundler-audit check --update
Mark Bandit false‑positive Edit baseline JSON → "false_positive": true
Fail on high Bandit issues only bandit -r . -lll
FindSecBugs high‑severity only findsecbugs -output report.sarif -medium -high -failOnHigh .
Validate AuditJS ignore file jq . auditjs-ignore.json
Preserve exit code with pipe set -o pipefail or check ${PIPESTATUS[0]}

Final Thought

Integrating these static analysis tools with the right installation method, output handling, and error‑checking logic turns a simple scan into a robust DevSecOps control. By following the patterns above, you’ll keep pipelines fast, results reproducible, and security findings actionable. Happy scanning!