Skip to content

Commit 4e34e38

Browse files
committed
test: added experimental feature to main malware check, tests updated to use MACARON_PATH
1 parent 6cbbef6 commit 4e34e38

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

tests/malware_analyzer/pypi/test_pypi_sourcecode_analyzer.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88

99
import pytest
1010

11-
import macaron
11+
from macaron import MACARON_PATH
1212
from macaron.errors import ConfigurationError, HeuristicAnalyzerValueError
1313
from macaron.malware_analyzer.pypi_heuristics.heuristics import HeuristicResult
1414
from macaron.malware_analyzer.pypi_heuristics.sourcecode.pypi_sourcecode_analyzer import PyPISourcecodeAnalyzer
1515

16+
RESOURCES_PATH = os.path.join(MACARON_PATH, "resources")
17+
1618

1719
def test_no_resources() -> None:
1820
"""Test for when the semgrep rules can't be found, so error."""
@@ -25,22 +27,22 @@ def test_no_defaults_section(mock_defaults: MagicMock) -> None:
2527
"""Test for when the heuristics.pypi in defaults isn't defined at all, so error."""
2628
mock_defaults.has_section.side_effect = lambda _: False
2729
with pytest.raises(ConfigurationError):
28-
_ = PyPISourcecodeAnalyzer(resources_path=os.path.join(os.path.dirname(macaron.__file__), "resources"))
30+
_ = PyPISourcecodeAnalyzer(resources_path=RESOURCES_PATH)
2931

3032

3133
@patch("macaron.malware_analyzer.pypi_heuristics.sourcecode.pypi_sourcecode_analyzer.defaults")
3234
def test_no_custom_path(mock_defaults: MagicMock) -> None:
3335
"""Test for when a default path isn't provided, so the custom rule path should be None."""
3436
mock_defaults.has_section.side_effect = lambda section: section == "heuristic.pypi"
3537
mock_defaults.__getitem__.side_effect = lambda _: (MagicMock(get=MagicMock(return_value=None)))
36-
analyzer = PyPISourcecodeAnalyzer(resources_path=os.path.join(os.path.dirname(macaron.__file__), "resources"))
38+
analyzer = PyPISourcecodeAnalyzer(resources_path=RESOURCES_PATH)
3739
assert analyzer.custom_rule_path is None
3840

3941
mock_defaults.has_section.side_effect = lambda section: section == "heuristic.pypi"
4042
mock_defaults.__getitem__.side_effect = lambda section: (
4143
MagicMock(get=MagicMock(return_value="" if section == "heuristic.pypi" else None))
4244
)
43-
analyzer = PyPISourcecodeAnalyzer(resources_path=os.path.join(os.path.dirname(macaron.__file__), "resources"))
45+
analyzer = PyPISourcecodeAnalyzer(resources_path=RESOURCES_PATH)
4446
assert analyzer.custom_rule_path is None
4547

4648

@@ -52,7 +54,7 @@ def test_nonexistent_rule_path(mock_defaults: MagicMock) -> None:
5254
MagicMock(get=MagicMock(return_value="some_random_path" if section == "heuristic.pypi" else None))
5355
)
5456
with pytest.raises(ConfigurationError):
55-
_ = PyPISourcecodeAnalyzer(resources_path=os.path.join(os.path.dirname(macaron.__file__), "resources"))
57+
_ = PyPISourcecodeAnalyzer(resources_path=RESOURCES_PATH)
5658

5759

5860
@patch("macaron.malware_analyzer.pypi_heuristics.sourcecode.pypi_sourcecode_analyzer.defaults")
@@ -64,12 +66,12 @@ def test_invalid_custom_rules(mock_defaults: MagicMock) -> None:
6466
MagicMock(get=MagicMock(return_value=os.path.abspath(__file__) if section == "heuristic.pypi" else None))
6567
)
6668
with pytest.raises(ConfigurationError):
67-
_ = PyPISourcecodeAnalyzer(resources_path=os.path.join(os.path.dirname(macaron.__file__), "resources"))
69+
_ = PyPISourcecodeAnalyzer(resources_path=RESOURCES_PATH)
6870

6971

7072
def test_no_sourcecode(pypi_package_json: MagicMock) -> None:
7173
"""Test for when there is no source code available, so error."""
72-
analyzer = PyPISourcecodeAnalyzer(resources_path=os.path.join(os.path.dirname(macaron.__file__), "resources"))
74+
analyzer = PyPISourcecodeAnalyzer(resources_path=RESOURCES_PATH)
7375

7476
pypi_package_json.package_sourcecode_path = ""
7577

@@ -103,7 +105,7 @@ def test_rules(
103105
MagicMock(get=MagicMock(return_value="" if section == "heuristic.pypi" else None))
104106
)
105107

106-
analyzer = PyPISourcecodeAnalyzer(resources_path=os.path.join(os.path.dirname(macaron.__file__), "resources"))
108+
analyzer = PyPISourcecodeAnalyzer(resources_path=RESOURCES_PATH)
107109

108110
pypi_package_json.package_sourcecode_path = sample_path
109111
analyzer.default_rule_path = os.path.join(analyzer.default_rule_path, rule_file)

tests/slsa_analyzer/checks/test_detect_malicious_metadata_check.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
import os
88
import urllib.parse
99
from pathlib import Path
10+
from unittest.mock import MagicMock, patch
1011

1112
import pytest
1213
from pytest_httpserver import HTTPServer
1314

15+
from macaron import MACARON_PATH
1416
from macaron.config.defaults import load_defaults
1517
from macaron.slsa_analyzer.build_tool.base_build_tool import BaseBuildTool
1618
from macaron.slsa_analyzer.checks.check_result import CheckResultType
@@ -22,20 +24,31 @@
2224
RESOURCE_PATH = Path(__file__).parent.joinpath("resources")
2325

2426

27+
@patch("macaron.malware_analyzer.pypi_heuristics.sourcecode.pypi_sourcecode_analyzer.global_config")
2528
@pytest.mark.parametrize(
26-
("purl", "expected"),
29+
("purl", "expected", "experimental"),
2730
[
2831
# TODO: This check is expected to FAIL for pkg:pypi/zlibxjson. However, after introducing the wheel presence heuristic,
2932
# a false negative has been introduced. Note that if the unit test were allowed to access the OSV
3033
# knowledge base, it would report the package as malware. However, we intentionally block unit tests
3134
# from reaching the network.
32-
("pkg:pypi/zlibxjson", CheckResultType.PASSED),
33-
("pkg:pypi/test", CheckResultType.UNKNOWN),
34-
("pkg:maven:test/test", CheckResultType.UNKNOWN),
35+
pytest.param("pkg:pypi/zlibxjson", CheckResultType.PASSED, False, id="test_malicious_pypi_package"),
36+
pytest.param("pkg:pypi/test", CheckResultType.UNKNOWN, False, id="test_unknown_pypi_package"),
37+
pytest.param("pkg:maven:test/test", CheckResultType.UNKNOWN, False, id="test_non_pypi_package"),
38+
# TODO: including source code analysis that detects flow from a remote point to a file write may assist in resolving
39+
# the issue of this false negative.
40+
pytest.param("pkg:pypi/zlibxjson", CheckResultType.PASSED, True, id="test_experimental_malicious_pypi_package"),
3541
],
3642
)
3743
def test_detect_malicious_metadata(
38-
httpserver: HTTPServer, tmp_path: Path, pip_tool: BaseBuildTool, macaron_path: Path, purl: str, expected: str
44+
mock_global_config: MagicMock,
45+
httpserver: HTTPServer,
46+
tmp_path: Path,
47+
pip_tool: BaseBuildTool,
48+
macaron_path: Path,
49+
purl: str,
50+
expected: str,
51+
experimental: bool,
3952
) -> None:
4053
"""Test that the check handles repositories correctly."""
4154
check = DetectMaliciousMetadataCheck()
@@ -44,6 +57,10 @@ def test_detect_malicious_metadata(
4457
ctx = MockAnalyzeContext(macaron_path=macaron_path, output_dir="", purl=purl)
4558
pypi_registry = PyPIRegistry()
4659
ctx.dynamic_data["package_registries"] = [PackageRegistryInfo(pip_tool, pypi_registry)]
60+
if experimental:
61+
ctx.dynamic_data["analyze_source"] = True
62+
63+
mock_global_config.resources_path = os.path.join(MACARON_PATH, "resources")
4764

4865
# Set up responses of PyPI endpoints using the httpserver plugin.
4966
with open(os.path.join(RESOURCE_PATH, "pypi_files", "zlibxjson.html"), encoding="utf8") as page:

0 commit comments

Comments
 (0)