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

Add: standalone plugin for evaluating dependencies with a graph #774

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

NiklasHargarter
Copy link
Contributor

@NiklasHargarter NiklasHargarter commented Dec 11, 2024

What

Adds a standalone plugin for evaluating script dependencies with a directed networkx graph.

checks for:

  • duplicate dependencies (a script declaring dependency on other script multiple times)
  • checking for cyclic dependencies
  • checking for missing dependencies
  • checking for cross feed dependencies (community script dependence on enterprise script). It is differentiated between dependencies that are behind a enterprise feed gate and those that are not.
  • category order
  • dependency on deprecated script

included functionality of normal plugins

  • dependencies (not included the subdirectory placement warning)
  • dependency_category_order (missing ACT_SCANNER error)
  • deprecated_dependency (i use the helper pattern regex not the one from the plugin)

Output

python logging levels for system information (error, warning, info)
normal additive verbosity up to -vv for result output.

Feed options

  • 21.04 (21.04 + common)
  • 22.04 (22.04 + common)
  • common
  • full (21.0 + 22.04 + common)

example call:
poetry run troubadix-dependency-graph ~/gb/vulnerability-tests/nasl --feed full --log info -vv

Execution Time

locally ~13 seconds

Why

When checking dependencies, it makes sense to analyse the whole feed, rather than just working on changed scripts. And working on the whole feed is easier with a standalone plugin that doesn't have to adhere to the Troubadix structure.

References

Checklist

  • Tests

Copy link

github-actions bot commented Dec 11, 2024

Conventional Commits Report

Type Number
Changed 4
Added 4

🚀 Conventional commits found.

Copy link

codecov bot commented Dec 11, 2024

Codecov Report

Attention: Patch coverage is 82.81250% with 33 lines in your changes missing coverage. Please review.

Project coverage is 80.00%. Comparing base (bd5b6c1) to head (8dc409b).

Files with missing lines Patch % Lines
troubadix/standalone_plugins/dependency_graph.py 82.81% 23 Missing and 10 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #774      +/-   ##
==========================================
+ Coverage   79.82%   80.00%   +0.17%     
==========================================
  Files          87       88       +1     
  Lines        3023     3215     +192     
  Branches      589      613      +24     
==========================================
+ Hits         2413     2572     +159     
- Misses        462      485      +23     
- Partials      148      158      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

github-actions bot commented Dec 12, 2024

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ❌ 1 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 8dc409b.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

License Issues

poetry.lock

PackageVersionLicenseIssue Type
semver3.0.2BSD-2-Clause AND BSD-3-ClauseIncompatible License
networkx3.4.2NullUnknown License

pyproject.toml

PackageVersionLicenseIssue Type
networkx^ 3.4.2NullUnknown License
Allowed Licenses: 0BSD, AGPL-3.0-or-later, Apache-2.0, BlueOak-1.0.0, BSD-2-Clause, BSD-3-Clause-Clear, BSD-3-Clause, BSL-1.0, CAL-1.0, CC-BY-3.0, CC-BY-4.0, CC-BY-SA-4.0, CC0-1.0, EPL-2.0, GPL-2.0-only, GPL-2.0-or-later, GPL-2.0, GPL-3.0-or-later, ISC, LGPL-2.0-only, LGPL-2.0-or-later, LGPL-2.1-only, LGPL-2.1-or-later, LGPL-2.1, LGPL-3.0-only, LGPL-3.0, LGPL-3.0-or-later, MIT, MIT-CMU, MPL-1.1, MPL-2.0, OFL-1.1, PSF-2.0, Python-2.0, Python-2.0.1, Unicode-DFS-2016, Unlicense

OpenSSF Scorecard

PackageVersionScoreDetails
pip/networkx 3.4.2 🟢 4.9
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 17 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 9Found 26/27 approved changesets -- score normalized to 9
Dangerous-Workflow⚠️ 0dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 9license file detected
Binary-Artifacts🟢 10no binaries found in the repo
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing🟢 10project is fuzzed
Security-Policy⚠️ 0security policy file not detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/semver 3.0.2 🟢 5.1
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 87 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 8
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review⚠️ 1Found 2/17 approved changesets -- score normalized to 1
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Vulnerabilities🟢 100 existing vulnerabilities detected
Signed-Releases⚠️ -1no releases found
Branch-Protection🟢 3branch protection is not maximal on development and all release branches
SAST🟢 9SAST tool detected but not run on all commits
pip/networkx ^ 3.4.2 🟢 4.9
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 17 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 9Found 26/27 approved changesets -- score normalized to 9
Dangerous-Workflow⚠️ 0dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 9license file detected
Binary-Artifacts🟢 10no binaries found in the repo
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing🟢 10project is fuzzed
Security-Policy⚠️ 0security policy file not detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • poetry.lock
  • pyproject.toml

class Script:
name: str
feed: str
dependencies: list[tuple[str, bool]] # (dependency_name, is_gated)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
dependencies: list[tuple[str, bool]] # (dependency_name, is_gated)
dependencies: set[tuple[str, bool]] # (dependency_name, is_gated)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using a set would interfere with the current check_duplicates. Would require checking for duplicate dependencies during setup, rather than afterwards with the other checks. Or store duplicates in some other way.

Comment on lines +383 to +391
has_errors = any(result.has_errors() for result in results)
has_warnings = any(result.has_warnings() for result in results)

if has_errors:
return 1
elif has_warnings:
return 2
else:
return 0
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
has_errors = any(result.has_errors() for result in results)
has_warnings = any(result.has_warnings() for result in results)
if has_errors:
return 1
elif has_warnings:
return 2
else:
return 0
if any(result.has_errors() for result in results):
return 1
elif any(result.has_warnings() for result in results):
return 2
else:
return 0

Can be inlined

Comment on lines +108 to +113
parser.add_argument(
"--feed",
choices=["21.04", "22.04", "common", "full"],
default="full",
help="feed",
)
Copy link
Member

Choose a reason for hiding this comment

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

https://docs.python.org/3/howto/enum.html#flag

Good example for Flags I think

Comment on lines +103 to +107
parser.add_argument(
"root",
type=directory_type,
help="directory that should be linted",
)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
parser.add_argument(
"root",
type=directory_type,
help="directory that should be linted",
)
parser.add_argument(
"root",
type=directory_type,
help="directory that should be linted",
)

can be defaulted to the VTDIR environment variable, which is used by convention by nasl devs

VTCategory,
)

EXTENSIONS = (".nasl",) # not sure if inc files can also have dependencies
Copy link
Member

Choose a reason for hiding this comment

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

I dont think so, but worth a question to the core members I think

Comment on lines +138 to +139
case _:
return []
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
case _:
return []
case _:
raise <Some Exception>

Should raise an Error, since none of the proper values were found


def get_scripts(directory) -> list[Script]:
scripts = []
# use path glob?
Copy link
Member

Choose a reason for hiding this comment

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

There is an example in troubadix with glob

files = root.rglob("*.nasl")

Comment on lines +187 to +199
def split_dependencies(value: str) -> list[str]:
"""
removes blank lines, strips comments, cleans dependencies,
splits them by commas, and excludes empty strings.
"""
return [
dep
for line in value.splitlines()
if line.strip() # Ignore blank or whitespace-only lines
# ignore comment, clean line of unwanted chars, split by ','
for dep in re.sub(r'[\'"\s]', "", line.split("#", 1)[0]).split(",")
if dep # Include only non-empty
]
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be encapsulated in the check_dependencies check and then imported.

My original code isnt good to begin with, having it duplicated only increases the mess

checks for a script depending on a script multiple times
"""
warnings = []
for script in scripts:
Copy link
Member

Choose a reason for hiding this comment

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

Need to come back to this, reminder to myself



def cross_feed_dependencies(graph, gated_status: bool) -> list[tuple[str, str]]:
"""
Copy link
Member

Choose a reason for hiding this comment

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

Need to come back to this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants