Skip to content

Commit

Permalink
Minor linting and optimization.
Browse files Browse the repository at this point in the history
Signed-off-by: Caroline Russell <[email protected]>
  • Loading branch information
cerrussell committed Feb 15, 2024
1 parent 7868478 commit 502ee8b
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 73 deletions.
5 changes: 3 additions & 2 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[tool.flake8]
[flake8]
ignore = E203, E266, E501, W503, W605
max-line-length = 80
exclude = blint/cyclonedx/spec.py
max-line-length = 99
max-complexity = 18
select = "B,C,E,F,W,T4,B9"
82 changes: 41 additions & 41 deletions blint/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from blint.binary import parse
from blint.logger import LOG, console
from blint.utils import (is_fuzzable_name, print_findings_table, )
from blint.checks import (check_nx, check_pie, # pylint: disable=unused-import
from blint.checks import (check_nx, check_pie, # noqa, pylint: disable=unused-import
check_relro, check_canary, check_rpath,
check_virtual_size, check_authenticode,
check_dll_characteristics, check_codesign,
Expand All @@ -34,7 +34,7 @@

review_files = []
if HAVE_RESOURCE_READER:
with contextlib.suppress(Exception):
with contextlib.suppress(NameError, FileNotFoundError):
review_files = (
resource.name
for resource in importlib.resources.files(
Expand Down Expand Up @@ -96,7 +96,7 @@ def get_resource(package, resource):
# you may have a security vulnerability!
resource_path = os.path.join(package_path, resource)

return open(resource_path, encoding="utf-8")
return open(resource_path, "r", encoding="utf-8")

# Could not resolve package path from __file__.
LOG.warning(f"Unable to load resource: {package}:{resource}")
Expand All @@ -105,43 +105,44 @@ def get_resource(package, resource):

# Load the rules
with get_resource("blint.data", "rules.yml") as fp:
raw_data = fp.read().split("---")
for tmp_data in raw_data:
if not tmp_data:
continue
rules_list = yaml.safe_load(tmp_data)
for rule in rules_list:
rules_dict[rule.get("id")] = rule
raw_rules = fp.read().split("---")
for tmp_data in raw_rules:
if not tmp_data:
continue
rules_list = yaml.safe_load(tmp_data)
for rule in rules_list:
rules_dict[rule.get("id")] = rule

# Load the default review methods
for review_methods_file in review_files:
raw_annotations = []
if DEBUG_MODE:
LOG.debug(f"Loading review file {review_methods_file}")
with get_resource("blint.data.annotations", review_methods_file) as fp:
raw_data = fp.read().split("---")
for tmp_data in raw_data:
if not tmp_data:
continue
methods_reviews_groups = yaml.safe_load(tmp_data)
exe_type_list = methods_reviews_groups.get("exe_type")
if isinstance(exe_type_list, str):
exe_type_list = [exe_type_list]
all_rules = methods_reviews_groups.get("rules")
method_rules_dict = {}
for rule in all_rules:
method_rules_dict[rule.get("id")] = rule
review_rules_cache[rule.get("id")] = rule
for etype in exe_type_list:
if methods_reviews_groups.get("group") == "METHOD_REVIEWS":
review_methods_dict[etype].append(method_rules_dict)
elif methods_reviews_groups.get("group") == "EXE_REVIEWS":
review_exe_dict[etype].append(method_rules_dict)
elif methods_reviews_groups.get("group") == "SYMBOL_REVIEWS":
review_symbols_dict[etype].append(method_rules_dict)
elif methods_reviews_groups.get("group") == "IMPORT_REVIEWS":
review_imports_dict[etype].append(method_rules_dict)
elif methods_reviews_groups.get("group") == "ENTRIES_REVIEWS":
review_entries_dict[etype].append(method_rules_dict)
raw_annotations = fp.read().split("---")
for tmp_data in raw_annotations:
if not tmp_data:
continue
methods_reviews_groups = yaml.safe_load(tmp_data)
exe_type_list = methods_reviews_groups.get("exe_type")
if isinstance(exe_type_list, str):
exe_type_list = [exe_type_list]
all_rules = methods_reviews_groups.get("rules")
method_rules_dict = {}
for rule in all_rules:
method_rules_dict[rule.get("id")] = rule
review_rules_cache[rule.get("id")] = rule
for etype in exe_type_list:
if methods_reviews_groups.get("group") == "METHOD_REVIEWS":
review_methods_dict[etype].append(method_rules_dict)
elif methods_reviews_groups.get("group") == "EXE_REVIEWS":
review_exe_dict[etype].append(method_rules_dict)
elif methods_reviews_groups.get("group") == "SYMBOL_REVIEWS":
review_symbols_dict[etype].append(method_rules_dict)
elif methods_reviews_groups.get("group") == "IMPORT_REVIEWS":
review_imports_dict[etype].append(method_rules_dict)
elif methods_reviews_groups.get("group") == "ENTRIES_REVIEWS":
review_entries_dict[etype].append(method_rules_dict)


def run_checks(f, metadata):
Expand Down Expand Up @@ -474,11 +475,11 @@ def run_review(self, metadata):
self._gen_review_lists(exe_type)
# Check if reviews are available for this exe type
if (
self.review_methods_list or
self.review_exe_list or
self.review_symbols_list or
self.review_imports_list or
self.review_entries_list
self.review_methods_list
or self.review_exe_list
or self.review_symbols_list
or self.review_imports_list
or self.review_entries_list
):
return self._review_lists(metadata)
return {}
Expand Down Expand Up @@ -634,8 +635,7 @@ def run_review_methods_symbols(self, review_list, functions_list):
continue
patterns = rule_obj.get("patterns")
for apattern in patterns:
if (found_pattern[apattern] > EVIDENCE_LIMIT or found_cid[
cid] > EVIDENCE_LIMIT):
if found_pattern[apattern] > EVIDENCE_LIMIT or found_cid[cid] > EVIDENCE_LIMIT:
continue
for afun in functions_list:
if ((apattern.lower() in afun.lower()) and not
Expand Down
4 changes: 2 additions & 2 deletions blint/checks.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=missing-function-docstring,unused-argument
from blint.utils import parse_pe_manifest


Expand Down Expand Up @@ -61,8 +62,7 @@ def check_dll_characteristics(f, metadata, rule_obj): # noqa
def check_codesign(f, metadata, rule_obj): # noqa
if metadata.get("code_signature"):
code_signature = metadata.get("code_signature")
return (not code_signature or
code_signature.get("available") is not False)
return not code_signature or code_signature.get("available") is not False
return True


Expand Down
5 changes: 1 addition & 4 deletions blint/sbom.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,7 @@ def trim_components(components):
list: A list of unique components after trimming duplicates.
"""
added_dict = {}
ret = []
for comp in components:
if not added_dict.get(comp.bom_ref.model_dump(mode="python")):
added_dict[comp.bom_ref.model_dump(mode="python")] = comp
for k in sorted(added_dict.keys()):
ret.append(added_dict[k])
return ret
return [added_dict[k] for k in sorted(added_dict.keys())]
30 changes: 17 additions & 13 deletions blint/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
from importlib.metadata import distribution
from pathlib import Path

import lief
from defusedxml.ElementTree import fromstring
from lief import lief_errors
from rich import box
from rich.table import Table
from blint.logger import console

from blint.logger import console, LOG

CHARSET = string.digits + string.ascii_letters + r"""!&@"""

Expand Down Expand Up @@ -371,7 +372,7 @@
],
"slack_webhook": [
re.compile(
r"""https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}"""
r"https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}"
)
],
"stripe": [
Expand Down Expand Up @@ -426,7 +427,8 @@ def is_base64(s):
try:
decoded = base64.b64decode(s)
return s.endswith("==") or base64.b64encode(decoded) == s.encode()
except (binascii.Error, TypeError, UnicodeError):
except (binascii.Error, TypeError, UnicodeError) as e:
LOG.debug(f"Caught {type(e)}: {e} while checking if {s} is base64")
return False


Expand Down Expand Up @@ -598,8 +600,11 @@ def is_exe(src):
"""
if os.path.isfile(src):
try:
return is_binary_string(open(src, "rb").read(1024))
except (AttributeError, TypeError, PermissionError):
with open(src, "rb") as f:
data = f.read(1024)
return is_binary_string(data)
except (TypeError, OverflowError, ValueError, OSError) as e:
LOG.debug(f"Caught {type(e)} while reading file: {src}")
return False
return False

Expand Down Expand Up @@ -703,17 +708,16 @@ def parse_pe_manifest(manifest):
for ele in child.iter():
attribs_dict[ele.tag.rpartition("}")[-1]] = ele.attrib
return attribs_dict
except (TypeError, AttributeError, IndexError):
except (TypeError, AttributeError, IndexError) as e:
LOG.debug(f"Caught {type(e)}: {e} while parsing PE manifest.")
return {}


def is_fuzzable_name(name_str):
"""
This function checks if a given name string is fuzzable.
"""
if name_str:
return any(n.lower() in name_str for n in fuzzable_names)
return ""
return any(n.lower() in name_str for n in fuzzable_names) if name_str else False


def print_findings_table(findings, files):
Expand Down Expand Up @@ -810,7 +814,7 @@ def cleanup_dict_lief_errors(old_dict):
"""
new_dict = {}
for key, value in old_dict.items():
if isinstance(value, lief_errors):
if isinstance(value, lief.lief_errors):
continue
if isinstance(value, dict):
entry = cleanup_dict_lief_errors(value)
Expand All @@ -832,7 +836,7 @@ def cleanup_list_lief_errors(d):
"""
new_lst = []
for dl in d:
if isinstance(dl, lief_errors):
if isinstance(dl, lief.lief_errors):
continue
if isinstance(dl, dict):
entry = cleanup_dict_lief_errors(dl)
Expand All @@ -841,4 +845,4 @@ def cleanup_list_lief_errors(d):
else:
entry = dl
new_lst.append(entry)
return new_lst
return new_lst
17 changes: 6 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
name = "blint"
version = "2.0.0"
description = "Linter and SBOM generator for binary files."
authors = ["Prabhu Subramanian <[email protected]>"]
maintainers= ["Prabhu Subramanian <[email protected]>", "Caroline Russell <[email protected]>"]
authors = ["Prabhu Subramanian <[email protected]>", "Caroline Russell <[email protected]>"]
license = "Apache-2.0"
readme = "README.md"
homepage = "https://github.com/OWASP-dep-scan/blint"
Expand Down Expand Up @@ -44,30 +43,26 @@ pytest-cov = "^4.0.0"
pyinstaller = "^6.3.0"

[tool.black]
line-length = 80
line-length = 99

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.pytest.ini_options]
#addopts = "--verbose --cov-append --cov-report term --cov blint"
addopts = "--verbose --cov-append --cov-report term --cov blint"

[tool.pylint]
generated-members = ["lief"]
ignore-paths = ["blint/cyclonedx/*", "blint/checks.py"]
ignore-paths = ["blint/cyclonedx/*"]
# Let's not fuss about long strings
ignore-long-lines = "[r|f]\""
disable = ["missing-module-docstring", "logging-fstring-interpolation"]

[tool.pylint.format]
max-line-length = 80
max-line-length = 99

[tool.pylint.design]
max-args = 6
max-nested-blocks = 6

[tool.pylint.logging]
logging-format-style = "new"

[tool.pylint.messages_control]
disable = "W0718, C0103, C0209, C0302, W0613, E1205"

0 comments on commit 502ee8b

Please sign in to comment.