Bandit: Setup, Configuration, and Best Practices
What Is Bandit?
Bandit is a security linter for Python source code. It is designed to identify common security issues in Python code by analyzing the abstract syntax tree (AST) of each file. Bandit can detect vulnerabilities such as hardcoded passwords, SQL injection, insecure deserialization, use of dangerous functions like eval() or pickle, and many other patterns that could lead to security flaws. It is developed and maintained by the OpenStack Security Project and is widely adopted in CI/CD pipelines to catch security issues early in the development lifecycle.
Bandit works by scanning each Python file for calls to functions and modules that are known to be potentially dangerous. It uses a set of plugins (called "tests") that are each responsible for a specific security concern. For example, the B101 test flags the use of assert statements that may be stripped out by Python optimization, and the B301 test warns about the use of the pickle module for deserialization. Bandit outputs a report listing each finding with its severity, confidence, and a description of the issue.
Because Bandit works statically (without executing the code), it is fast and safe to run on any codebase, including untrusted code. It is an essential tool for any Python developer who wants to build secure applications, especially in environments where security is a priority such as web applications, data processing pipelines, or any system handling sensitive data.
Why Bandit Matters
Security vulnerabilities in software can have devastating consequences: data breaches, financial loss, and damage to reputation. Many common security flaws in Python applications arise from using unsafe APIs incorrectly or from overlooking best practices. Bandit helps developers catch these issues before they reach production.
Shift-left security is the practice of finding and fixing security issues as early as possible in the development process. By integrating Bandit into your development workflow—whether in your editor, pre-commit hooks, or CI pipeline—you can catch vulnerabilities at commit time rather than after deployment. This reduces the cost and effort required to fix them.
Bandit is especially important because:
- It detects both obvious and subtle security issues that manual code review might miss.
- It provides consistent, repeatable analysis across your entire codebase.
- It helps enforce secure coding standards across a team.
- It is open source, free, and actively maintained.
For projects that need to comply with security standards (e.g., OWASP, PCI DSS), Bandit can be a key part of the security assurance process. It can also be customized to ignore false positives and to add project-specific rules.
How to Set Up Bandit
Installation
Bandit is available via pip. The simplest way to install it is:
pip install bandit
If you are using a virtual environment (which is recommended), activate it first:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install bandit
You can also add Bandit to your project's requirements-dev.txt or Pipfile for reproducible builds.
Basic Usage
Once installed, run Bandit on a single file or an entire directory:
bandit my_script.py
To scan a whole project:
bandit -r .
The -r flag enables recursive scanning of directories. By default, Bandit will output a report to stdout showing all issues found, along with their severity (HIGH, MEDIUM, LOW) and confidence (HIGH, MEDIUM, LOW).
Understanding the Output
A typical Bandit output looks like this:
>> Issue: [B301:blacklist] Use of insecure pickle function.
Severity: High Confidence: High
Location: app/data_handler.py:25
More Info: https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html#b301-pickle
The format includes the test ID (e.g., B301), a short description, severity, confidence, file location, and a link to documentation. You can use the -f flag to output in different formats like JSON, HTML, or CSV:
bandit -r . -f html -o report.html
Configuration Options
Bandit allows extensive customization through a configuration file. You can specify which tests to run, set severity thresholds, exclude paths, and add custom plugins. The configuration file is typically named .bandit or bandit.yaml and placed at the root of your project.
Creating a Basic Configuration File
Create a file named .bandit (YAML format) in your project root:
# .bandit
exclude_dirs:
- tests
- .venv
- build
skips:
- B101 # Skip assert warnings (if you use them intentionally)
- B404 # Skip warnings about subprocess import (if controlled)
tests:
- B301
- B302
- B303
- B304
- B305
- B306
- B307
- B308
- B309
- B310
- B311
- B312
- B313
- B314
- B315
- B316
- B317
- B318
- B319
- B320
- B321
- B322
- B323
- B324
- B325
- B326
- B327
- B328
- B329
- B330
- B331
- B332
- B333
- B334
- B335
- B336
- B337
- B338
- B339
- B340
- B341
- B342
- B343
- B344
- B345
- B346
- B347
- B348
- B349
- B350
- B351
- B352
- B353
- B354
- B355
- B356
- B357
- B358
- B359
- B360
- B361
- B362
- B363
- B364
- B365
- B366
- B367
- B368
- B369
- B370
- B371
- B372
- B373
- B374
- B375
- B376
- B377
- B378
- B379
- B380
- B381
- B382
- B383
- B384
- B385
- B386
- B387
- B388
- B389
- B390
- B391
- B392
- B393
- B394
- B395
- B396
- B397
- B398
- B399
- B400
- B401
- B402
- B403
- B404
- B405
- B406
- B407
- B408
- B409
- B410
- B411
- B412
- B413
- B414
- B415
- B416
- B417
- B418
- B419
- B420
- B421
- B422
- B423
- B424
- B425
- B426
- B427
- B428
- B