Skip to content

Commit

Permalink
Merge branch 'main' into pytorch-checks
Browse files Browse the repository at this point in the history
  • Loading branch information
lukehinds authored Aug 24, 2024
2 parents 7da10e7 + 68022aa commit 11e00d8
Show file tree
Hide file tree
Showing 28 changed files with 304 additions and 73 deletions.
4 changes: 3 additions & 1 deletion .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ body:
label: Bandit version
description: Run "bandit --version" if unsure of version number
options:
- 1.7.7 (Default)
- 1.7.9 (Default)
- 1.7.8
- 1.7.7
- 1.7.6
- 1.7.5
- 1.7.4
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/build-publish-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ jobs:
ref: ${{ github.event_name == 'release' && github.ref || env.RELEASE_TAG }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3

- name: Log in to GitHub Container Registry
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Install Cosign
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0
uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0
with:
cosign-release: 'v2.2.2'

Expand All @@ -51,7 +51,7 @@ jobs:
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6
with:
context: .
file: ./docker/Dockerfile
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/asottile/reorder-python-imports
rev: v3.12.0
rev: v3.13.0
hooks:
- id: reorder-python-imports
args: [--application-directories, '.:src', --py38-plus]
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.4.0
rev: 24.4.2
hooks:
- id: black
args: [--line-length=79, --target-version=py38]
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.2
rev: v3.16.0
hooks:
- id: pyupgrade
args: [--py38-plus]
Expand Down
2 changes: 2 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ python:
- requirements: doc/requirements.txt
- method: pip
path: .
extra_requirements:
- sarif
26 changes: 26 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,29 @@ source of origin using the following cosign command:
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Where `<version>` is the release version of Bandit.

Sponsors
--------

The development of Bandit is made possible by the following sponsors:

.. list-table::
:width: 100%
:class: borderless

* - .. image:: https://github.githubassets.com/assets/tidelift-8cea37dea8fc.svg
:target: https://tidelift.com/lifter/search/pypi/bandit
:alt: Tidelift
:width: 88

- .. image:: https://avatars.githubusercontent.com/u/110237746?s=200&v=4
:target: https://stacklok.com/
:alt: Stacklok
:width: 88

- .. image:: https://avatars.githubusercontent.com/u/1396951?s=70&v=4
:target: https://sentry.io/
:alt: Sentry
:width: 88

If you also ❤️ Bandit, please consider sponsoring.
4 changes: 2 additions & 2 deletions bandit/blacklists/calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ def gen_blacklist():
"telnetlib",
"B312",
issue.Cwe.CLEARTEXT_TRANSMISSION,
["telnetlib.*"],
["telnetlib.Telnet"],
"Telnet-related functions are being called. Telnet is considered "
"insecure. Use SSH or some other encrypted protocol.",
"HIGH",
Expand Down Expand Up @@ -662,7 +662,7 @@ def gen_blacklist():
"ftplib",
"B321",
issue.Cwe.CLEARTEXT_TRANSMISSION,
["ftplib.*"],
["ftplib.FTP"],
"FTP-related functions are being called. FTP is considered "
"insecure. Use SSH/SFTP/SCP or some other encrypted protocol.",
"HIGH",
Expand Down
19 changes: 13 additions & 6 deletions bandit/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,16 +450,17 @@ def main():
args.confidence = 4
# Other strings will be blocked by argparse

try:
b_conf = b_config.BanditConfig(config_file=args.config_file)
except utils.ConfigError as e:
LOG.error(e)
sys.exit(2)

# Handle .bandit files in projects to pass cmdline args from file
ini_options = _get_options_from_ini(args.ini_path, args.targets)
if ini_options:
# prefer command line, then ini file
args.config_file = _log_option_source(
parser.get_default("configfile"),
args.config_file,
ini_options.get("configfile"),
"config file",
)

args.excluded_paths = _log_option_source(
parser.get_default("excluded_paths"),
args.excluded_paths,
Expand Down Expand Up @@ -592,6 +593,12 @@ def main():
"path of a baseline report",
)

try:
b_conf = b_config.BanditConfig(config_file=args.config_file)
except utils.ConfigError as e:
LOG.error(e)
sys.exit(2)

if not args.targets:
parser.print_usage()
sys.exit(2)
Expand Down
3 changes: 1 addition & 2 deletions bandit/core/blacklisting.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#
# SPDX-License-Identifier: Apache-2.0
import ast
import fnmatch

from bandit.core import issue

Expand Down Expand Up @@ -55,7 +54,7 @@ def blacklist(context, config):
name = context.call_keywords["name"]
for check in blacklists[node_type]:
for qn in check["qualnames"]:
if name is not None and fnmatch.fnmatch(name, qn):
if name is not None and name == qn:
return report_issue(check, name)

if node_type.startswith("Import"):
Expand Down
2 changes: 1 addition & 1 deletion bandit/core/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def _get_literal_value(self, literal):
elif isinstance(literal, ast.Tuple):
return_tuple = tuple()
for ti in literal.elts:
return_tuple = return_tuple + (self._get_literal_value(ti),)
return_tuple += (self._get_literal_value(ti),)
literal_value = return_tuple

elif isinstance(literal, ast.Set):
Expand Down
3 changes: 2 additions & 1 deletion bandit/core/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Cwe:
MULTIPLE_BINDS = 605
IMPROPER_CHECK_OF_EXCEPT_COND = 703
INCORRECT_PERMISSION_ASSIGNMENT = 732
INAPPROPRIATE_ENCODING_FOR_OUTPUT_CONTEXT = 838

MITRE_URL_PATTERN = "https://cwe.mitre.org/data/definitions/%s.html"

Expand Down Expand Up @@ -84,7 +85,7 @@ def __init__(
ident=None,
lineno=None,
test_id="",
col_offset=0,
col_offset=-1,
end_col_offset=0,
):
self.severity = severity
Expand Down
12 changes: 10 additions & 2 deletions bandit/core/node_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def __init__(
):
self.debug = debug
self.nosec_lines = nosec_lines
self.seen = 0
self.scores = {
"SEVERITY": [0] * len(constants.RANKING),
"CONFIDENCE": [0] * len(constants.RANKING),
Expand Down Expand Up @@ -209,7 +208,6 @@ def pre_visit(self, node):
self.context["filename"] = self.fname
self.context["file_data"] = self.fdata

self.seen += 1
LOG.debug(
"entering: %s %s [%s]", hex(id(node)), type(node), self.depth
)
Expand Down Expand Up @@ -286,4 +284,14 @@ def process(self, data):
"""
f_ast = ast.parse(data)
self.generic_visit(f_ast)
# Run tests that do not require access to the AST,
# but only to the whole file source:
self.context = {
"file_data": self.fdata,
"filename": self.fname,
"lineno": 0,
"linerange": [0, 1],
"col_offset": 0,
}
self.update_scores(self.tester.run_tests(self.context, "File"))
return self.scores
6 changes: 5 additions & 1 deletion bandit/core/test_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ def checks(*args):
def wrapper(func):
if not hasattr(func, "_checks"):
func._checks = []
func._checks.extend(utils.check_ast_node(a) for a in args)
for arg in args:
if arg == "File":
func._checks.append("File")
else:
func._checks.append(utils.check_ast_node(arg))

LOG.debug("checks() decorator executed")
LOG.debug(" func._checks: %s", func._checks)
Expand Down
5 changes: 3 additions & 2 deletions bandit/core/tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def run_tests(self, raw_context, checktype):
tests = self.testset.get_tests(checktype)
for test in tests:
name = test.__name__
# execute test with the an instance of the context class
# execute test with an instance of the context class
temp_context = copy.copy(raw_context)
context = b_context.Context(temp_context)
try:
Expand All @@ -66,7 +66,8 @@ def run_tests(self, raw_context, checktype):
if result.lineno is None:
result.lineno = temp_context["lineno"]
result.linerange = temp_context["linerange"]
result.col_offset = temp_context["col_offset"]
if result.col_offset == -1:
result.col_offset = temp_context["col_offset"]
result.end_col_offset = temp_context.get(
"end_col_offset", 0
)
Expand Down
2 changes: 1 addition & 1 deletion bandit/formatters/xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
"Test ID: %s Severity: %s Confidence: %s\nCWE: %s\n%s\n"
"Location %s:%s"
)
text = text % (
text %= (
issue.test_id,
issue.severity,
issue.confidence,
Expand Down
4 changes: 2 additions & 2 deletions bandit/plugins/crypto_request_no_cert_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@
@test.checks("Call")
@test.test_id("B501")
def request_with_no_cert_validation(context):
HTTP_VERBS = ("get", "options", "head", "post", "put", "patch", "delete")
HTTPX_ATTRS = ("request", "stream", "Client", "AsyncClient") + HTTP_VERBS
HTTP_VERBS = {"get", "options", "head", "post", "put", "patch", "delete"}
HTTPX_ATTRS = {"request", "stream", "Client", "AsyncClient"} | HTTP_VERBS
qualname = context.call_function_name_qual.split(".")[0]

if (
Expand Down
2 changes: 1 addition & 1 deletion bandit/plugins/injection_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ def start_process_with_partial_path(context, config):
):
node = context.node.args[0]
# some calls take an arg list, check the first part
if isinstance(node, ast.List):
if isinstance(node, ast.List) and node.elts:
node = node.elts[0]

# make sure the param is a string literal and not a var name
Expand Down
2 changes: 1 addition & 1 deletion bandit/plugins/injection_wildcard.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def linux_commands_wildcard_injection(context, config):
argument_string = ""
if isinstance(call_argument, list):
for li in call_argument:
argument_string = argument_string + f" {li}"
argument_string += f" {li}"
elif isinstance(call_argument, str):
argument_string = call_argument

Expand Down
24 changes: 17 additions & 7 deletions bandit/plugins/request_without_timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
B113: Test for missing requests timeout
=======================================
This plugin test checks for ``requests`` calls without a timeout specified.
This plugin test checks for ``requests`` or ``httpx`` calls without a timeout
specified.
Nearly all production code should use this parameter in nearly all requests,
Failure to do so can cause your program to hang indefinitely.
Expand All @@ -17,7 +18,7 @@
.. code-block:: none
>> Issue: [B113:request_without_timeout] Requests call without timeout
>> Issue: [B113:request_without_timeout] Call to requests without timeout
Severity: Medium Confidence: Low
CWE: CWE-400 (https://cwe.mitre.org/data/definitions/400.html)
More Info: https://bandit.readthedocs.io/en/latest/plugins/b113_request_without_timeout.html
Expand All @@ -27,7 +28,7 @@
4 requests.get('https://gmail.com', timeout=None)
--------------------------------------------------
>> Issue: [B113:request_without_timeout] Requests call with timeout set to None
>> Issue: [B113:request_without_timeout] Call to requests with timeout set to None
Severity: Medium Confidence: Low
CWE: CWE-400 (https://cwe.mitre.org/data/definitions/400.html)
More Info: https://bandit.readthedocs.io/en/latest/plugins/b113_request_without_timeout.html
Expand All @@ -42,6 +43,9 @@
.. versionadded:: 1.7.5
.. versionchanged:: 1.7.10
Added check for httpx module
""" # noqa: E501
import bandit
from bandit.core import issue
Expand All @@ -51,23 +55,29 @@
@test.checks("Call")
@test.test_id("B113")
def request_without_timeout(context):
http_verbs = ("get", "options", "head", "post", "put", "patch", "delete")
HTTP_VERBS = {"get", "options", "head", "post", "put", "patch", "delete"}
HTTPX_ATTRS = {"request", "stream", "Client", "AsyncClient"} | HTTP_VERBS
qualname = context.call_function_name_qual.split(".")[0]

if qualname == "requests" and context.call_function_name in http_verbs:
if (
qualname == "requests"
and context.call_function_name in HTTP_VERBS
or qualname == "httpx"
and context.call_function_name in HTTPX_ATTRS
):
# check for missing timeout
if context.check_call_arg_value("timeout") is None:
return bandit.Issue(
severity=bandit.MEDIUM,
confidence=bandit.LOW,
cwe=issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION,
text="Requests call without timeout",
text=f"Call to {qualname} without timeout",
)
# check for timeout=None
if context.check_call_arg_value("timeout", "None"):
return bandit.Issue(
severity=bandit.MEDIUM,
confidence=bandit.LOW,
cwe=issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION,
text="Requests call with timeout set to None",
text=f"Call to {qualname} with timeout set to None",
)
Loading

0 comments on commit 11e00d8

Please sign in to comment.