Categories

Static Application Security Testing (SAST)

Import Options

API Import

UI Import

Universal Importer (Pro)

File Types

JSON

Integrations

Bandit

Bandit is an open-source static application security testing (SAST) tool designed to identify common security vulnerabilities in Python code by analyzing Abstract Syntax Trees (AST) to detect issues such as hardcoded passwords, SQL injection, use of weak cryptographic algorithms, and insecure library usage. The tool provides automated security scanning with configurable plugins and generates detailed reports with severity and confidence ratings, enabling developers to address security flaws early in the development lifecycle before code reaches production. 

Bandit Integration with DefectDojo


Bandit is the most widely used open-source static analysis tool in the Python security ecosystem — maintained by the Python Code Quality Authority and designed specifically to find common security issues in Python code. It runs fast, requires no configuration to get started, and covers the patterns that matter most in Python applications: hardcoded credentials, dangerous function usage, insecure deserialization, weak cryptography, SQL injection risks, shell injection, and more. For security teams with Python in their stack, Bandit is typically the first SAST tool deployed and often the one with the broadest CI coverage. The gap is operational: Bandit findings live in JSON output files and CI logs unless something moves them into a workflow. Integrating Bandit with DefectDojo closes that gap — findings enter a persistent lifecycle with deduplication, SLA enforcement, remediation tracking, and portfolio-level reporting that raw Bandit output can never provide.

Why Bandit Matters

Bandit occupies a foundational role in Python security programs — it is purpose-built for the language, actively maintained, and covers the vulnerability patterns that appear most frequently in real-world Python codebases.


  • Bandit's plugin architecture covers over 40 built-in security checks organized by test ID (B1xx through B7xx), targeting categories including injection risks, cryptographic weaknesses, hardcoded secrets, dangerous function calls, insecure network configurations, XML vulnerabilities, and subprocess misuse
  • It operates directly on Python AST (Abstract Syntax Tree) rather than text pattern matching, giving it accuracy advantages over regex-based approaches — especially for detecting issues in dynamically constructed code
  • Confidence and severity are reported independently for every finding, allowing teams to filter and prioritize based on both dimensions rather than relying on a single combined rating — a High severity / Low confidence finding warrants different treatment than a High / High
  • JSON output via --format json produces structured data that DefectDojo consumes directly, with line numbers, code snippets, CWE references, and test IDs included in every finding record
  • Bandit integrates into CI pipelines with a single pip install and one CLI command — there is no license server, no account registration, and no configuration file required for basic coverage
  • Custom plugins and configuration files (.bandit) allow teams to tune checks, exclude test directories, and suppress known false positive patterns — giving the tool longevity in production codebases where untuned scanners create noise

Advantages of This Integration

Bandit tells you where Python security issues exist in your code. DefectDojo tracks whether they were fixed, who decided what, and how your Python security posture is trending over time.


  • Persistent finding records across scan cycles: Each time Bandit runs against a codebase, reimporting into DefectDojo updates existing findings rather than creating a fresh record set. You can see which issues have been present across multiple CI runs, which were resolved between scans, and which have been open for weeks without action — context that CI log output doesn't preserve.
  • SLA enforcement by severity and confidence: DefectDojo applies configurable SLA policies across imported Bandit findings. High severity findings with High confidence get the tightest remediation targets; Low confidence findings can be handled on a slower review cadence. Breach tracking surfaces overdue items in dashboards without manual status chasing.
  • Deduplication across repositories and services: The same insecure pattern appearing across multiple Python services — for example, subprocess.call with shell=True across a microservices fleet — surfaces in DefectDojo as a pattern worth addressing at the framework or code review standard level, not just service-by-service.
  • False positive management that survives reimports: Bandit produces false positives, particularly for intentional uses of flagged patterns in non-security-sensitive contexts. Findings marked as false positives in DefectDojo are retained across reimports — the next Bandit run won't re-open them, and the documented rationale is available for audit review rather than relying on inline # nosec comments alone.
  • Cross-repository Python portfolio visibility: Security teams with dozens of Python repositories get aggregated metrics in DefectDojo — open findings by severity, test ID, age, and SLA status — without manually reviewing individual Bandit outputs per repository. This aggregate view is what drives security training decisions, code review standards updates, and framework-level remediation initiatives.
  • Developer-facing remediation tickets: Triaged Bandit findings push from DefectDojo to Jira, GitHub Issues, or ServiceNow with test ID, affected file and line, code snippet, CWE reference, and remediation guidance — giving developers what they need to understand and fix the issue without needing to run Bandit themselves or navigate a security tool.
  • Trend analysis over time: DefectDojo retains scan history across reimports, enabling trend analysis of Python security posture — whether findings are decreasing after training initiatives, whether specific test IDs cluster in particular services, and whether new development is introducing issues at the same rate as older code.

How This Integration Works

Bandit produces JSON output via its CLI that DefectDojo's Bandit parser consumes directly.


Step 1 — Run Bandit and capture JSON output


Install Bandit:


pip install bandit


Run against a Python project and capture JSON output:


# Scan a directory recursively with JSON output

bandit -r ./src --format json --output bandit-results.json


# Include severity and confidence level filtering

bandit -r ./src \

--format json \

--output bandit-results.json \

--level medium \

--confidence medium


# Exclude test directories (common pattern)

bandit -r ./src \

--format json \

--output bandit-results.json \

--exclude ./src/tests,./src/test_*


# Scan with a specific configuration file

bandit -r ./src \

--format json \

--output bandit-results.json \

--configfile .bandit


For CI pipeline integration, capture the output file regardless of exit code:


# Bandit exits non-zero when findings are present

# Use || true to capture output even when findings exist

bandit -r ./src --format json --output bandit-results.json || true


Step 2 — Import into DefectDojo


Use Bandit Scan as the scan type:


curl -X POST https://<defectdojo-host>/api/v2/import-scan/ \

-H "Authorization: Token <your-api-token>" \

-F "scan_type=Bandit Scan" \

-F "file=@bandit-results.json" \

-F "engagement=<engagement-id>" \

-F "product=<product-id>" \

-F "active=true" \

-F "verified=false"


Step 3 — Reimport for recurring scans


For repositories scanned on every CI run or merge to main, use the reimport endpoint to update existing findings rather than accumulate redundant test records:


curl -X POST https://<defectdojo-host>/api/v2/reimport-scan/ \

-H "Authorization: Token <your-api-token>" \

-F "scan_type=Bandit Scan" \

-F "file=@bandit-results.json" \

-F "test=<test-id>"


DefectDojo marks findings absent from the new scan as resolved, creates records for new findings, and leaves previously false-positived or risk-accepted findings untouched.

Data Granularity: What Gets Imported

Field

Source in Bandit Output

Notes

Title

test_name + test_id

e.g., "hardcoded_password_string [B105]"

Severity

issue_severity

HIGH, MEDIUM, LOW

Confidence

issue_confidence

HIGH, MEDIUM, LOW — independent of severity

CWE ID

issue_cwe.id

CWE identifier mapped by Bandit for the test

CWE Link

issue_cwe.link

Direct link to the CWE entry

Description

issue_text

Bandit's explanation of the security issue

File Path

filename

Relative path to the affected Python file

Line Number

line_number

Line where the issue was detected

Line Range

line_range

Full range of lines involved in the finding

Code Snippet

code

The actual Python code that triggered the finding

Test ID

test_id

Bandit plugin identifier e.g., B101, B301, B602

More Info

more_info

Link to Bandit documentation for the specific test

Use Cases

In a CI/CD pipeline for Python web services: Bandit runs on every pull request against Django or Flask services. Results import into DefectDojo via the API at the end of the scan stage. Security engineers triage new findings weekly, with High severity / High confidence findings assigned immediately and Medium findings batched into a regular review cycle. Findings marked false positive in DefectDojo — for example, a B101 assert usage that is intentional in a non-security context — don't re-appear on subsequent scans, keeping the active queue clean.


Across a data science and ML codebase: Python data science codebases frequently use patterns that Bandit flags — pickle deserialization (B301), subprocess calls for data pipeline orchestration (B602/B603), and YAML loading (B506). A security team imports Bandit findings for a data platform's Python codebase into DefectDojo, triages against actual exploitability in the data pipeline context, documents risk acceptances for patterns that are intentional, and tracks the subset that genuinely warrants remediation — without letting the full Bandit output volume mask the real risks.


For a Python security hardening initiative: An AppSec team identifies that weak cryptography usage (B303, B304, B305) and hardcoded credentials (B105, B106, B107) are recurring patterns across their Python portfolio. They run Bandit across all Python repositories, import results into DefectDojo, and use the aggregated view to prioritize remediation by test ID across services. The initiative has a tracked start state, assigned remediation owners per service, and a target closure date — managed as a DefectDojo program rather than as individual unconnected tickets.


During a security review of a Python infrastructure automation codebase: Ansible playbooks, Terraform Python providers, and internal CLI tooling written in Python are scanned with Bandit as part of a periodic security review. Results import into a dedicated DefectDojo engagement for infrastructure code security, separate from application SAST findings. Infrastructure-specific findings — shell injection risks in automation scripts, hardcoded credentials in deployment tooling — are tracked and assigned to the platform engineering team with appropriate SLA treatment for infrastructure risk.

Operational Tips

  • Use || true in CI to decouple scan exit code from pipeline failure: Bandit exits non-zero when any findings are present, which fails the CI pipeline stage by default. Capture the JSON output regardless of exit code and handle pipeline gate logic separately — for example, post-processing the JSON to fail the build only on new High / High findings that aren't already tracked in DefectDojo as accepted.
  • Tune exclusions before importing at scale: Bandit scans of large Python codebases without exclusions frequently flag test files for patterns (B101 assert usage, B106 hardcoded test credentials) that are intentional in test contexts. Configuring --exclude for test directories or using a .bandit configuration file to skip specific test IDs in test paths reduces false positive volume before it reaches DefectDojo.
  • Use severity and confidence together for prioritization: DefectDojo imports Bandit's severity and confidence independently. During triage, focus first on High severity / High confidence findings — these represent the clearest risk. Medium severity / Low confidence findings can be reviewed on a slower cadence or batch-accepted with documented rationale if the pattern is consistently non-exploitable in your codebase context.
  • Map one DefectDojo product per Python repository: A one-to-one mapping between Python repositories and DefectDojo products keeps deduplication clean and ownership clear. For monorepos containing multiple Python services, consider mapping products to the top-level service directories and running Bandit per service rather than across the entire monorepo in a single scan.
  • Prefer DefectDojo risk acceptances over # nosec comments for documented decisions: Bandit supports inline # nosec suppression comments to silence specific findings. For decisions that warrant documentation — accepted risk, compensating controls, business context — prefer capturing the rationale as a risk acceptance in DefectDojo instead. The decision is then auditable and carries an expiration date, rather than being silently embedded in source code where it may be copied forward indefinitely.
  • Track test ID frequency across your portfolio: DefectDojo's tag filtering and reporting enable analysis of which Bandit test IDs appear most frequently across your Python portfolio. Patterns here inform security training priorities — if B602 (subprocess shell injection) appears in 15 repositories, that's a training and code review standard problem, not just a per-repository finding.
  • Pair Bandit with a secrets scanner for complete coverage: Bandit's hardcoded credential checks (B105, B106, B107) catch common patterns but are not exhaustive. Pairing Bandit with a dedicated secrets scanner (Detect Secrets, Trufflehog, Gitleaks) and importing both into DefectDojo under the same engagement gives more complete coverage of the credentials exposure surface in Python codebases — with both sets of findings tracked in the same lifecycle workflow.

Start Your Free

Trial Today

Unify your security pipeline and orchestrate peace of mind with DefectDojo. We are security experts and here to help.