Skip to content

Commit

Permalink
Support ignoring blacklists by name (#1046)
Browse files Browse the repository at this point in the history
* Support ignoring blacklists by name

This extends nosec parsing to enable blacklists to be ignored by
their name, not just by id.

There were 2 issues with the previous implementation:
1. The regex did not match numbers, which is needed for some names,
   such as md5. The code would only match "md" in this case.
2. The function that maps plugin names to ids only considered plugins
   but not blacklists.

Both of these are now addressed.

Closes #988

* Relabel plugin to test to avoid confusion

The original code considered plugins, but not blacklists.
Since the code now correctly considers both types of tests,
the function and variables should be renamed to avoid confusion.

* Fix lint
  • Loading branch information
costaparas committed Aug 18, 2023
1 parent 215f014 commit 6d1d11c
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 14 deletions.
8 changes: 4 additions & 4 deletions bandit/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,14 @@ def convert_names_to_ids(self):
updated_profiles = {}
for name, profile in (self.get_option("profiles") or {}).items():
# NOTE(tkelsey): can't use default of get() because value is
# sometimes explicity 'None', for example when the list if given in
# yaml but not populated with any values.
# sometimes explicitly 'None', for example when the list is given
# in yaml but not populated with any values.
include = {
(extman.get_plugin_id(i) or i)
(extman.get_test_id(i) or i)
for i in (profile.get("include") or [])
}
exclude = {
(extman.get_plugin_id(i) or i)
(extman.get_test_id(i) or i)
for i in (profile.get("exclude") or [])
}
updated_profiles[name] = {"include": include, "exclude": exclude}
Expand Down
8 changes: 5 additions & 3 deletions bandit/core/extension_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ def test_has_id(plugin):
self.plugins_by_id = {p.plugin._test_id: p for p in self.plugins}
self.plugins_by_name = {p.name: p for p in self.plugins}

def get_plugin_id(self, plugin_name):
if plugin_name in self.plugins_by_name:
return self.plugins_by_name[plugin_name].plugin._test_id
def get_test_id(self, test_name):
if test_name in self.plugins_by_name:
return self.plugins_by_name[test_name].plugin._test_id
if test_name in self.blacklist_by_name:
return self.blacklist_by_name[test_name]["id"]
return None

def load_blacklists(self, blacklist_namespace):
Expand Down
14 changes: 7 additions & 7 deletions bandit/core/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

LOG = logging.getLogger(__name__)
NOSEC_COMMENT = re.compile(r"#\s*nosec:?\s*(?P<tests>[^#]+)?#?")
NOSEC_COMMENT_TESTS = re.compile(r"(?:(B\d+|[a-z_]+),?)+", re.IGNORECASE)
NOSEC_COMMENT_TESTS = re.compile(r"(?:(B\d+|[a-z\d_]+),?)+", re.IGNORECASE)
PROGRESS_THRESHOLD = 50


Expand Down Expand Up @@ -460,17 +460,17 @@ def _find_candidate_matches(unmatched_issues, results_list):


def _find_test_id_from_nosec_string(extman, match):
plugin_id = extman.check_id(match)
if plugin_id:
test_id = extman.check_id(match)
if test_id:
return match
# Finding by short_id didn't work, let's check the plugin name
plugin_id = extman.get_plugin_id(match)
if not plugin_id:
# Finding by short_id didn't work, let's check the test name
test_id = extman.get_test_id(match)
if not test_id:
# Name and short id didn't work:
LOG.warning(
"Test in comment: %s is not a test name or id, ignoring", match
)
return plugin_id # We want to return None or the string here regardless
return test_id # We want to return None or the string here regardless


def _parse_nosec_comment(comment):
Expand Down
3 changes: 3 additions & 0 deletions examples/nosec.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import subprocess # nosec: import_subprocess
from cryptography.hazmat.primitives import hashes
hashes.SHA1() # nosec: md5
subprocess.Popen('/bin/ls *', shell=True) #nosec (on the line)
subprocess.Popen('/bin/ls *', #nosec (at the start of function call)
shell=True)
Expand Down

0 comments on commit 6d1d11c

Please sign in to comment.