Bandit Documentation

repository·main·Indexed 27 days ago

https://github.com/pycqa/bandit

A security linter for Python that identifies common security vulnerabilities by analyzing the Abstract Syntax Tree (AST) of source code. It includes a CLI for scanning files, a baseline tool for comparing findings between Git commits, and a configuration generator for creating profiles to include or skip specific tests.

Tokens
8.4K
Snippets
14
Records
74
Agent score
92%

What's inside Bandit

  1. Overview of Bandit

    main
    Bandit is a security linter designed to find common security issues in Python code. It works by processing each file, building an Abstract Syntax Tree (AST), and running specialized plugins against the AST nodes to identify vulnerabilities. After scanning the files, it generates a report of the findings.
  2. Overview of Bandit security scanning

    main
    Bandit is a security tool for Python that identifies common security vulnerabilities. It works by processing Python files, building an Abstract Syntax Tree (AST) for each, and executing specialized plugins against the AST nodes. After the scan is complete, Bandit generates a report summarizing the findings.
  3. Use the B101: assert_used plugin

    main
    The B101: assert_used plugin detects the use of the assert statement in Python code. In Python, assert statements can be optimized away when the code is run with optimizations (e.g., using the -O flag), which can lead to security vulnerabilities if the assertion is used for critical logic or security checks. This plugin flags these instances to encourage developers to use explicit error handling instead.
  4. Implement Blacklist Plugins

    main

    Bandit allows extending its security checks by implementing blacklist plugins for imports and function calls. These plugins are discovered at startup via the bandit.blacklists entry point.

    By convention:

    • Blacklisted calls should use IDs in the B3xx range.
    • Blacklisted imports should use IDs in the B4xx range.

    Plugin functions must return a dictionary mapping AST node types to lists of blacklist data. Supported node types are:

    • Call: For blacklisting function calls.
    • Import: For blacklisting module imports (this also covers ImportFrom and calls to the built-in __import__() method).

    To simplify implementation, use the utility method bandit.blacklists.utils.build_conf_dict to construct the required data dictionaries.

  5. Run Bandit scans

    main

    Use the bandit command to scan Python code. You can scan specific files, entire directories recursively, or use standard input.

    Common flags:

    • -r: Recursive scan.
    • -n <number>: Show N lines of context.
    • --severity-level=<level>: Filter by severity (e.g., high).
    • -lll: Shorthand for high severity.
    • -p <profile>: Run using a specific plugin profile (e.g., ShellInjection).
    • -h: Show help information.
  6. Detect insecure hashlib functions with B324

    main
    Bandit includes a plugin (B324) that scans for the use of insecure hash functions within the hashlib module. This plugin identifies calls to functions that are known to be cryptographically broken or weak, such as md5 or sha1, which should not be used for security-sensitive purposes like password hashing or digital signatures.
  7. Integrate Bandit with IDEs

    main

    Bandit can be used within various code editors via plugins to provide real-time security linting. Supported IDE integrations include:

    • Visual Studio Code: Use Bandit by PyCQA.
    • Sublime Text: Use SublimeLinter-bandit.
    • Vim/Neovim: Use Asynchronous Lint Engine (ALE).
    • Emacs: Use flycheck-pycheckers.
  8. Write a custom Bandit test plugin

    main

    To extend Bandit's security detection capabilities, you can create custom test plugins.

    Follow these steps:

    1. Create a test case: Add a Python file to an examples/ directory containing the vulnerability you want to detect.
    2. Implement the test function: Create a Python source file containing a function that accepts a context parameter. The context object allows you to query the element being examined or access the raw AST node.
    3. Decorate the function: Use @bandit.checks decorators to specify which AST nodes the plugin should target:
      • @bandit.checks('Call')
      • @bandit.checks('Import', 'ImportFrom')
      • @bandit.checks('Str')
    4. Return an Issue: If a vulnerability is found, return a bandit.Issue object specifying severity, confidence, and text.
    5. Register the plugin: Use the bandit.plugins entry point (see registration guide).
    6. Verify: Run Bandit against your example file to ensure the vulnerability is detected.
    @bandit.checks('Call')
    def prohibit_unsafe_deserialization(context):
        if 'unsafe_load' in context.call_function_name_qual:
            return bandit.Issue(
                severity=bandit.HIGH,
                confidence=bandit.HIGH,
                text="Unsafe deserialization detected."
            )
  9. Register a Bandit plugin via entry points

    main

    To make your plugin discoverable by Bandit, you must register it using entry points in your packaging configuration.

    Using setuptools (setup.py): Add the entry_points argument to your setup() call.

    Using pbr (setup.cfg): Add the plugin under the [entry_points] section.

    # Using setuptools in setup.py
    setup(
        # ...
        entry_points={'bandit.plugins': ['mako = bandit_mako']}
    )
    # Using pbr in setup.cfg
    [entry_points]
    bandit.plugins =
        mako = bandit_mako
  10. Select the correct Python version for running Bandit

    main

    When choosing which Python version to use for running Bandit, select the version that matches the Python version of the project you are analyzing.

    Bandit relies on the standard library's ast module to parse code. Because the ast module can only parse syntax valid for the specific interpreter version it is running under, using an older Python version to analyze code written for a newer version will result in syntax errors.

    Guidelines:

    • If your project is compatible only with Python 3.9, install and run Bandit under Python 3.9.
    • If your project is compatible only with Python 3.10, run Bandit under Python 3.10.
    • If your project supports multiple versions, you may run Bandit under any of those supported versions.