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

Adding support for running YARA as sourcecode rules #401

Merged
merged 32 commits into from
Jul 17, 2024
Merged
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8937fca
adding initial yara support
sobregosodd Jun 25, 2024
741a505
adding initial yara support
sobregosodd Jun 25, 2024
ce64828
adding correct messaging
sobregosodd Jun 25, 2024
3186c52
tide before hotfix
sobregosodd Jun 25, 2024
e93fe97
Merge branch 'main' into s.obregoso/feat_yara
sobregosodd Jun 26, 2024
49a8766
merge from main
sobregosodd Jun 26, 2024
7b92492
adding initial yara support
sobregosodd Jun 25, 2024
62b0c37
add support for yara
sobregosodd Jun 27, 2024
23f4c17
add support for yara
sobregosodd Jun 27, 2024
0425ec8
tide
sobregosodd Jun 27, 2024
d69960d
adding initial yara support
sobregosodd Jun 25, 2024
6ba3b73
add support for yara
sobregosodd Jun 27, 2024
ac52e2e
tide
sobregosodd Jun 27, 2024
1c2d084
adding rules detection
sobregosodd Jun 27, 2024
9d6f301
tide cli
sobregosodd Jun 28, 2024
de01733
improving cli to admit dynamic amount of languages
sobregosodd Jul 1, 2024
134ae0e
typo in test
sobregosodd Jul 3, 2024
a3e5412
adding comments to click dynamic grouping
sobregosodd Jul 8, 2024
21b2213
Merge branch 'main' into s.obregoso/feat_yara
sobregosodd Jul 8, 2024
b2be94c
lint
sobregosodd Jul 8, 2024
d10b480
Adding docs
sobregosodd Jul 10, 2024
fbb0648
Adding docs
sobregosodd Jul 10, 2024
d2fff62
removing ecosystem hardocded code
sobregosodd Jul 15, 2024
84d861e
added sarif tests and reworked the SOURCECODE_RULES variable concept
sobregosodd Jul 15, 2024
ccf15e2
Merge branch 'main' into s.obregoso/feat_yara
sobregosodd Jul 15, 2024
aeb8355
adding dependencies
sobregosodd Jul 15, 2024
ff0466b
fixing missing rename references
sobregosodd Jul 15, 2024
0a46085
missing step in workflow
sobregosodd Jul 15, 2024
2e2c63f
turning SOURCECODE filter into generator
sobregosodd Jul 16, 2024
a8f5f4a
docs and test
sobregosodd Jul 16, 2024
9bdc69c
docs and test
sobregosodd Jul 16, 2024
aecc17c
addressing PR comments
sobregosodd Jul 17, 2024
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
195 changes: 67 additions & 128 deletions guarddog/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
""" PyPI Package Malware Scanner
""" Package Malware Scanner

CLI command that scans a PyPI package version for user-specified malware flags.
CLI command that scans a package version for user-specified malware flags.
Includes rules based on package registry metadata and source code analysis.
"""

Expand All @@ -22,10 +22,6 @@
from guarddog.scanners.scanner import PackageScanner
from functools import reduce

ALL_RULES = reduce(
lambda a, b: a | b,
map(lambda e: set(get_sourcecode_rules(e)) | set(get_metadata_detectors(e).keys()), [e for e in ECOSYSTEM])
)
PYPI_RULES = set(get_sourcecode_rules(ECOSYSTEM.PYPI)) | set(get_metadata_detectors(ECOSYSTEM.PYPI).keys())
NPM_RULES = set(get_sourcecode_rules(ECOSYSTEM.NPM)) | set(get_metadata_detectors(ECOSYSTEM.NPM).keys())

Expand All @@ -51,6 +47,11 @@ def common_options(fn):


def legacy_rules_options(fn):
ALL_RULES = reduce(
lambda a, b: a | b,
map(lambda e: set(get_sourcecode_rules(e)) | set(get_metadata_detectors(e).keys()), [e for e in ECOSYSTEM])
)

fn = click.option(
"-r",
"--rules",
Expand All @@ -66,40 +67,6 @@ def legacy_rules_options(fn):
return fn


def npm_options(fn):
rules = _get_all_rules(ECOSYSTEM.NPM)
fn = click.option(
"-r",
"--rules",
multiple=True,
type=click.Choice(rules, case_sensitive=False),
)(fn)
fn = click.option(
"-x",
"--exclude-rules",
multiple=True,
type=click.Choice(rules, case_sensitive=False),
)(fn)
return fn


def pypi_options(fn):
rules = _get_all_rules(ECOSYSTEM.PYPI)
fn = click.option(
"-r",
"--rules",
multiple=True,
type=click.Choice(rules, case_sensitive=False),
)(fn)
fn = click.option(
"-x",
"--exclude-rules",
multiple=True,
type=click.Choice(rules, case_sensitive=False),
)(fn)
return fn


def verify_options(fn):
fn = click.option(
"--output-format",
Expand Down Expand Up @@ -148,7 +115,6 @@ def cli(log_level):
stdoutHandler = logging.StreamHandler(stream=sys.stdout)
stdoutHandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
logger.addHandler(stdoutHandler)
pass


def _get_all_rules(ecosystem: ECOSYSTEM) -> set[str]:
Expand Down Expand Up @@ -323,98 +289,71 @@ def _list_rules(ecosystem):
print(table)


@cli.group
def npm(**kwargs):
"""Scan a npm package or verify a npm project"""
pass


@cli.group
def pypi(**kwargs):
"""Scan a PyPI package or verify a PyPI project"""
pass


@npm.command("scan")
@common_options
@scan_options
@npm_options
def scan_npm(
target, version, rules, exclude_rules, output_format, exit_non_zero_on_finding
):
"""Scan a given npm package"""
return _scan(
target,
version,
rules,
exclude_rules,
output_format,
exit_non_zero_on_finding,
ECOSYSTEM.NPM,
)


@npm.command("verify")
@common_options
@verify_options
@npm_options
def verify_npm(target, rules, exclude_rules, output_format, exit_non_zero_on_finding):
"""Verify a given npm project"""
return _verify(
target,
rules,
exclude_rules,
output_format,
exit_non_zero_on_finding,
ECOSYSTEM.NPM,
)


@pypi.command("scan")
@common_options
@scan_options
@pypi_options
def scan_pypi(
target, version, rules, exclude_rules, output_format, exit_non_zero_on_finding
):
"""Scan a given PyPI package"""
return _scan(
target,
version,
rules,
exclude_rules,
output_format,
exit_non_zero_on_finding,
ECOSYSTEM.PYPI,
)

class CliEcosystem(click.Group):
def __init__(self, ecosystem: ECOSYSTEM):
christophetd marked this conversation as resolved.
Show resolved Hide resolved
sobregosodd marked this conversation as resolved.
Show resolved Hide resolved
super().__init__()
self.name = ecosystem.name.lower()
self.ecosystem = ecosystem

def rule_options(fn):
rules = _get_all_rules(self.ecosystem)
fn = click.option(
"-r",
"--rules",
multiple=True,
type=click.Choice(rules, case_sensitive=False),
)(fn)
fn = click.option(
"-x",
"--exclude-rules",
multiple=True,
type=click.Choice(rules, case_sensitive=False),
)(fn)
return fn

@click.command("scan", help=f"Scan a given {self.ecosystem.name} package")
@common_options
@scan_options
@rule_options
def scan_ecosystem(
target, version, rules, exclude_rules, output_format, exit_non_zero_on_finding
):
return _scan(
target,
version,
rules,
exclude_rules,
output_format,
exit_non_zero_on_finding,
self.ecosystem,
)

@pypi.command("verify")
@common_options
@verify_options
@pypi_options
def verify_pypi(target, rules, exclude_rules, output_format, exit_non_zero_on_finding):
"""Verify a given Pypi project"""
return _verify(
target,
rules,
exclude_rules,
output_format,
exit_non_zero_on_finding,
ECOSYSTEM.PYPI,
)
@click.command("verify", help=f"Verify a given {self.ecosystem.name} package")
@common_options
@verify_options
@rule_options
def verify_ecosystem(target, rules, exclude_rules, output_format, exit_non_zero_on_finding):
return _verify(
target,
rules,
exclude_rules,
output_format,
exit_non_zero_on_finding,
ECOSYSTEM.PYPI,
)

@click.command("list-rules", help=f"List available rules for {self.ecosystem.name}")
def list_rules_ecosystem():
return _list_rules(self.ecosystem)

@pypi.command("list-rules")
def list_rules_pypi():
"""Print available rules for PyPI"""
return _list_rules(ECOSYSTEM.PYPI)
self.add_command(scan_ecosystem, "scan")
self.add_command(verify_ecosystem, "verify")
self.add_command(list_rules_ecosystem, "list-rules")


@npm.command("list-rules")
def list_rules_npm():
"""Print available rules for npm"""
return _list_rules(ECOSYSTEM.NPM)
# Adding all ecosystems as subcommands
for e in ECOSYSTEM:
cli.add_command(CliEcosystem(e), e.name.lower())


@cli.command("verify", deprecated=True)
Expand Down
Loading