Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of GitHub Bandit action #6

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/bandit-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Bandit Code Scan

on:
pull_request:
branches: [ main ]

permissions:
pull-requests: write
jobs:
bandit-action:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- name: Run Bandit Scan
uses: ./
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
path: "."
recursive: "true"
21 changes: 15 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
FROM python:3.8-slim
FROM ghcr.io/pycqa/bandit/bandit:latest

LABEL "maintainer"="PyCQA <[email protected]>"
LABEL "repository"="https://github.com/PyCQA/bandit-action"
LABEL "homepage"="https://github.com/PyCQA/bandit-action"
ENV GITHUB_TOKEN=""
ENV GITHUB_REPOSITORY=""

RUN pip install bandit
# Install additional dependencies if necessary
RUN apk add --no-cache git bash python3 py3-pip && \
pip install PyGithub

# Copy the entrypoint script
COPY entrypoint.sh /entrypoint.sh

# Make the entrypoint script executable
RUN chmod +x /entrypoint.sh

# Assuming the Dockerfile is located at the root of the repository
COPY post_comment.py /post_comment.py

ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
117 changes: 115 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,115 @@
# bandit-action
GitHub Action for Bandit
# GitHub Action for Bandit

This is the official GitHub Action for running
[Bandit](https://bandit.readthedocs.io/en/latest/), developed by the maintainers
of Bandit. It is designed to be configurable and easy to use.

## Features

- :gear: Fully configurable with input parameters and support for config files.
- :speech_balloon: Posts scan results as a comment on pull requests.

## Inputs

| Name | Description | Default |
|----------------------|-------------------------------------------------------------|---------|
| `recursive` | Find and process files in subdirectories. | `false` |
| `aggregate` | Aggregate output by vulnerability or by filename. | `vuln` |
| `context_lines` | Maximum number of code lines to output for each issue. | |
| `config_file` | Optional config file to use for selecting plugins. | |
| `profile` | Profile to use, defaults to executing all tests. | |
| `tests` | Comma-separated list of test IDs to run. | |
| `skips` | Comma-separated list of test IDs to skip. | |
| `severity_level` | Report only issues of a given severity level or higher. | `low` |
| `confidence_level` | Report only issues of a given confidence level or higher. | `low` |
| `verbose` | Output extra information like excluded and included files. | `false` |
| `debug` | Turn on debug mode. | `false` |
| `quiet` | Only show output in the case of an error. | `false` |
| `ignore_nosec` | Do not skip lines with `# nosec` comments. | `false` |
| `exclude_paths` | Comma-separated list of paths to exclude from scan. | |
| `baseline` | Path of a baseline report to compare against. | |
| `ini_path` | Path to a `.bandit` file that supplies command line args. | |
| `exit_zero` | Exit with 0 even with results found.

| :memo: | We do not expose args for output/format,message_template, as we need to hardcore the report for the PR comment feature|
|---------------|:----------------------------------------------------------------------------------------------------------------------|

## Usage

To use the action, add the following to a GitHub workflow file (e.g. `.github/workflows/bandit.yml`):

### Basic Example

```yaml
name: Bandit Code Scan

on:
pull_request:
branches: [ main ]

permissions:
pull-requests: write

jobs:
bandit-action:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Bandit Scan
uses: ./
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
path: "."
exit_zero: "true"
recursive: "true"
```

```yaml
name: Bandit Code Scan

on: [push, pull_request]

permissions:
pull-requests: write

jobs:
bandit-action:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Bandit Scan
uses: ./
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
path: "."
exit_zero: true
recursive: true
aggregate: vuln
context_lines: 3
config_file: .bandit
profile: bandit
tests: B101,B102
skips: B103
severity_level: low
confidence_level: low
verbose: true
debug: true
quiet: false
ignore_nosec: false
exclude_paths: tests,docs
baseline: baseline.json
ini_path: .bandit
exit_zero: false
```

## Contributing

If you would like to contribute to this project, please open an issue or a pull
request.

## License

This GitHub Action is distributed under the Apache License, Version 2.0, see
[LICENSE](LICENSE) for more information.
171 changes: 92 additions & 79 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,82 +1,95 @@
name: Bandit
description: Run Bandit
author: '@ericwb'

inputs:
args:
description: |
Optional arguments:
-r, --recursive find and process files in subdirectories
-a {file,vuln}, --aggregate {file,vuln}
aggregate output by vulnerability (default) or by
filename
-n CONTEXT_LINES, --number CONTEXT_LINES
maximum number of code lines to output for each issue
-c CONFIG_FILE, --configfile CONFIG_FILE
optional config file to use for selecting plugins and
overriding defaults
-p PROFILE, --profile PROFILE
profile to use (defaults to executing all tests)
-t TESTS, --tests TESTS
comma-separated list of test IDs to run
-s SKIPS, --skip SKIPS
comma-separated list of test IDs to skip
-l, --level report only issues of a given severity level or higher
(-l for LOW, -ll for MEDIUM, -lll for HIGH)
--severity-level {all,low,medium,high}
report only issues of a given severity level or higher.
"all" and "low" are likely to produce the same results,
but it is possible for rules to be undefined which will
not be listed in "low".
-i, --confidence report only issues of a given confidence level or
higher (-i for LOW, -ii for MEDIUM, -iii for HIGH)
--confidence-level {all,low,medium,high}
report only issues of a given confidence level or higher.
"all" and "low" are likely to produce the same results,
but it is possible for rules to be undefined which will
not be listed in "low".
-f {csv,custom,html,json,screen,txt,xml,yaml}, --format {csv,custom,html,json,screen,txt,xml,yaml}
specify output format
--msg-template MSG_TEMPLATE
specify output message template (only usable with
--format custom), see CUSTOM FORMAT section for list
of available values
-o [OUTPUT_FILE], --output [OUTPUT_FILE]
write report to filename
-v, --verbose output extra information like excluded and included
files
-d, --debug turn on debug mode
-q, --quiet, --silent
only show output in the case of an error
--ignore-nosec do not skip lines with # nosec comments
-x EXCLUDED_PATHS, --exclude EXCLUDED_PATHS
comma-separated list of paths (glob patterns
supported) to exclude from scan (note that these are
in addition to the excluded paths provided in the
config file) (default:
.svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg)
-b BASELINE, --baseline BASELINE
path of a baseline report to compare against (only
JSON-formatted files are accepted)
--ini INI_PATH path to a .bandit file that supplies command line
arguments
--exit-zero exit with 0, even with results found
--version show program's version number and exit
required: false
default: '-h'
targets:
description: |
Source file(s) or directory(s) to be tested
name: Bandit Code Scan
description: 'Run Bandit code scans on your Python codebase'
inputs:
GITHUB_TOKEN:
description: 'GitHub token'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe GitHub now refers these to "personal access tokens". And the latest version have fine-grained permissions that can be assigned. Therefore guidance on what minimal set of permissions needed here would be useful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right, this is an inbuilt Token that is created for each workflow run and then destroyed at the end. No need for the user to do anything:

https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret

required: true
recursive:
description: 'Find and process files in subdirectories'
required: false
default: 'false'
aggregate:
description: 'Aggregate output by vulnerability or by filename'
required: false
default: 'vuln'
context_lines:
description: 'Maximum number of code lines to output for each issue'
required: false
config_file:
description: 'Optional config file to use'
required: false
profile:
description: 'Profile to use'
required: false
tests:
description: 'Comma-separated list of test IDs to run'
required: false
skips:
description: 'Comma-separated list of test IDs to skip'
required: false
severity_level:
description: 'Report only issues of a given severity level or higher'
required: false
confidence_level:
description: 'Report only issues of a given confidence level or higher {all,low,medium,high}'
required: false
verbose:
description: 'Output extra information like excluded and included files'
required: false
default: 'false'
debug:
description: 'Turn on debug mode'
required: false
default: 'false'
quiet:
description: 'Only show output in the case of an error'
required: false
default: 'false'
ignore_nosec:
description: 'Do not skip lines with # nosec comments'
required: false
default: 'false'
exclude_paths:
description: 'Comma-separated list of paths to exclude from scan'
required: false
baseline:
description: 'Path of a baseline report to compare against'
required: false
ini_path:
description: 'Path to a .bandit file that supplies command line arguments'
required: false
path:
description: 'Path to scan'
required: true

default: '.'
level:
description: 'Report only issues of a given severity level or higher'
required: false
default: 'low'
exit_zero:
description: 'Exit with 0, even with results found'
required: false
default: 'false'
runs:
using: docker
image: Dockerfile
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.args }}
env:
TARGETS: ${{ inputs.targets }}

branding:
icon: 'shield'
color: 'yellow'
- ${{ inputs.recursive }}
- ${{ inputs.aggregate }}
- ${{ inputs.context_lines }}
- ${{ inputs.config_file }}
- ${{ inputs.profile }}
- ${{ inputs.tests }}
- ${{ inputs.skips }}
- ${{ inputs.severity_level }}
- ${{ inputs.confidence_level }}
- ${{ inputs.verbose }}
- ${{ inputs.debug }}
- ${{ inputs.quiet }}
- ${{ inputs.ignore_nosec }}
- ${{ inputs.exclude_paths }}
- ${{ inputs.baseline }}
- ${{ inputs.ini_path }}
- ${{ inputs.path }}
- ${{ inputs.level }}
- ${{ inputs.exit_zero }}
Loading