Skip to content

Commit

Permalink
refactor: reworded 'anomalistic' to 'anomalous'
Browse files Browse the repository at this point in the history
  • Loading branch information
art1f1c3R committed Jan 13, 2025
1 parent 434e322 commit ad04616
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 38 deletions.
9 changes: 5 additions & 4 deletions src/macaron/config/defaults.ini
Original file line number Diff line number Diff line change
Expand Up @@ -584,12 +584,13 @@ include = *
[heuristic.pypi]
releases_frequency_threshold = 2
# The gap threshold.
# The timedelta indicate the gap between the date maintainer registers their pypi's account and the date of latest release.
# The timedelta represents the gap between when the date maintainer registers their pypi account, and the
# date of the latest release.
timedelta_threshold_of_join_release = 5

# Any major version above this value is detected as anomalistic and marked as suspicious
# Any major version above this value is detected as anomalous and marked as suspicious.
major_threshold = 20
# Any epoch number avove this value is detected as anomalistic and marked as suspicious
# Any epoch number avove this value is detected as anomalous and marked as suspicious.
epoch_threshold = 3
# The number of days +/- the day of publish the calendar versioning day may be
# The number of days +/- the day of publish the calendar versioning day may be.
day_publish_error = 4
6 changes: 3 additions & 3 deletions src/macaron/malware_analyzer/pypi_heuristics/heuristics.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ class Heuristics(str, Enum):
#: Indicates that the setup.py file contains suspicious imports, such as base64 and requests.
SUSPICIOUS_SETUP = "suspicious_setup"

#: Indicates that the package does not include a .whl file
#: Indicates that the package does not include a .whl file.
WHEEL_ABSENCE = "wheel_absence"

#: Indicates that the package has an unusually large version number for a single release
ANOMALISTIC_VERSION = "anomalistic_version"
#: Indicates that the package has an unusually large version number for a single release.
ANOMALOUS_VERSION = "anomalous_version"


class HeuristicResult(str, Enum):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright (c) 2024 - 2025, Oracle and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.

"""The heuristic analyzer to check for an anomalistic package version."""
"""The heuristic analyzer to check for an anomalous package version."""

import logging
from enum import Enum
Expand All @@ -19,11 +19,11 @@
logger: logging.Logger = logging.getLogger(__name__)


class AnomalisticVersionAnalyzer(BaseHeuristicAnalyzer):
class AnomalousVersionAnalyzer(BaseHeuristicAnalyzer):
"""
Analyze the version number (if there is only a single release) to detect if it is anomalistic.
Analyze the version number (if there is only a single release) to detect if it is anomalous.
A version number is anomalistic if it is above the thresholds for an epoch, major, or minor value.
A version number is anomalous if any of its values are greater than the epoch, major, or minor threshold values.
If the version does not adhere to PyPI standards (PEP 440, as per the 'packaging' module), this heuristic
cannot analyze it.
Expand Down Expand Up @@ -62,8 +62,8 @@ class AnomalisticVersionAnalyzer(BaseHeuristicAnalyzer):

def __init__(self) -> None:
super().__init__(
name="anomalistic_version_analyzer",
heuristic=Heuristics.ANOMALISTIC_VERSION,
name="anomalous_version_analyzer",
heuristic=Heuristics.ANOMALOUS_VERSION,
depends_on=[(Heuristics.ONE_RELEASE, HeuristicResult.FAIL)],
)
self.major_threshold, self.epoch_threshold, self.day_publish_error = self._load_defaults()
Expand Down
34 changes: 17 additions & 17 deletions src/macaron/slsa_analyzer/checks/detect_malicious_metadata_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from macaron.json_tools import JsonType, json_extract
from macaron.malware_analyzer.pypi_heuristics.base_analyzer import BaseHeuristicAnalyzer
from macaron.malware_analyzer.pypi_heuristics.heuristics import HeuristicResult, Heuristics
from macaron.malware_analyzer.pypi_heuristics.metadata.anomalistic_version import AnomalisticVersionAnalyzer
from macaron.malware_analyzer.pypi_heuristics.metadata.anomalous_version import AnomalousVersionAnalyzer
from macaron.malware_analyzer.pypi_heuristics.metadata.closer_release_join_date import CloserReleaseJoinDateAnalyzer
from macaron.malware_analyzer.pypi_heuristics.metadata.empty_project_link import EmptyProjectLinkAnalyzer
from macaron.malware_analyzer.pypi_heuristics.metadata.high_release_frequency import HighReleaseFrequencyAnalyzer
Expand Down Expand Up @@ -76,7 +76,7 @@ class MaliciousMetadataFacts(CheckFacts):
CloserReleaseJoinDateAnalyzer,
SuspiciousSetupAnalyzer,
WheelAbsenceAnalyzer,
AnomalisticVersionAnalyzer,
AnomalousVersionAnalyzer,
]


Expand Down Expand Up @@ -104,11 +104,11 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.FAIL, # Suspicious Setup
HeuristicResult.FAIL, # Wheel Absence
HeuristicResult.FAIL, # Anomalistic Version
HeuristicResult.FAIL, # Anomalous Version
# No project link, only one release, and the maintainer released it shortly
# after account registration.
# The setup.py file contains suspicious imports and .whl file isn't present.
# Anomalistic version has no effect.
# Anomalous version has no effect.
): Confidence.HIGH,
(
HeuristicResult.FAIL, # Empty Project
Expand All @@ -119,11 +119,11 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.FAIL, # Suspicious Setup
HeuristicResult.FAIL, # Wheel Absence
HeuristicResult.PASS, # Anomalistic Version
HeuristicResult.PASS, # Anomalous Version
# No project link, only one release, and the maintainer released it shortly
# after account registration.
# The setup.py file contains suspicious imports and .whl file isn't present.
# Anomalistic version has no effect.
# Anomalous version has no effect.
): Confidence.HIGH,
(
HeuristicResult.FAIL, # Empty Project
Expand All @@ -134,7 +134,7 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.FAIL, # Suspicious Setup
HeuristicResult.FAIL, # Wheel Absence
HeuristicResult.SKIP, # Anomalistic Version
HeuristicResult.SKIP, # Anomalous Version
# No project link, frequent releases of multiple versions without modifying the content,
# and the maintainer released it shortly after account registration.
# The setup.py file contains suspicious imports and .whl file isn't present.
Expand All @@ -148,7 +148,7 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.FAIL, # Suspicious Setup
HeuristicResult.FAIL, # Wheel Absence
HeuristicResult.SKIP, # Anomalistic Version
HeuristicResult.SKIP, # Anomalous Version
# No project link, frequent releases of multiple versions,
# and the maintainer released it shortly after account registration.
# The setup.py file contains suspicious imports and .whl file isn't present.
Expand All @@ -162,7 +162,7 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.PASS, # Suspicious Setup
HeuristicResult.PASS, # Wheel Absence
HeuristicResult.SKIP, # Anomalistic Version
HeuristicResult.SKIP, # Anomalous Version
# No project link, frequent releases of multiple versions without modifying the content,
# and the maintainer released it shortly after account registration. Presence/Absence of
# .whl file has no effect
Expand All @@ -176,7 +176,7 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.PASS, # Suspicious Setup
HeuristicResult.FAIL, # Wheel Absence
HeuristicResult.SKIP, # Anomalistic Version
HeuristicResult.SKIP, # Anomalous Version
# No project link, frequent releases of multiple versions without modifying the content,
# and the maintainer released it shortly after account registration. Presence/Absence of
# .whl file has no effect
Expand All @@ -190,7 +190,7 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.FAIL, # Suspicious Setup
HeuristicResult.FAIL, # Wheel Absence
HeuristicResult.SKIP, # Anomalistic Version
HeuristicResult.SKIP, # Anomalous Version
# All project links are unreachable, frequent releases of multiple versions,
# and the maintainer released it shortly after account registration.
# The setup.py file contains suspicious imports and .whl file isn't present.
Expand All @@ -204,11 +204,11 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.PASS, # Suspicious Setup
HeuristicResult.PASS, # Wheel Absence
HeuristicResult.FAIL, # Anomalistic Version
HeuristicResult.FAIL, # Anomalous Version
# No project link, only one release, and the maintainer released it shortly
# after account registration.
# The setup.py file has no effect and .whl file is present.
# The version number is anomalistic.
# The version number is anomalous.
): Confidence.MEDIUM,
(
HeuristicResult.FAIL, # Empty Project
Expand All @@ -219,11 +219,11 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.FAIL, # Suspicious Setup
HeuristicResult.PASS, # Wheel Absence
HeuristicResult.FAIL, # Anomalistic Version
HeuristicResult.FAIL, # Anomalous Version
# No project link, only one release, and the maintainer released it shortly
# after account registration.
# The setup.py file has no effect and .whl file is present.
# The version number is anomalistic.
# The version number is anomalous.
): Confidence.MEDIUM,
(
HeuristicResult.FAIL, # Empty Project
Expand All @@ -234,11 +234,11 @@ class MaliciousMetadataFacts(CheckFacts):
HeuristicResult.FAIL, # Closer Release Join Date
HeuristicResult.SKIP, # Suspicious Setup
HeuristicResult.PASS, # Wheel Absence
HeuristicResult.FAIL, # Anomalistic Version
HeuristicResult.FAIL, # Anomalous Version
# No project link, only one release, and the maintainer released it shortly
# after account registration.
# The setup.py file has no effect and .whl file is present.
# The version number is anomalistic.
# The version number is anomalous.
): Confidence.MEDIUM,
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# Copyright (c) 2024 - 2025, Oracle and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.

"""Tests for heuristic detecting anomalistic version numbers"""
"""Tests for heuristic detecting anomalous version numbers"""
from unittest.mock import MagicMock

import pytest

from macaron.errors import HeuristicAnalyzerValueError
from macaron.malware_analyzer.pypi_heuristics.heuristics import HeuristicResult
from macaron.malware_analyzer.pypi_heuristics.metadata.anomalistic_version import AnomalisticVersionAnalyzer, Versioning
from macaron.malware_analyzer.pypi_heuristics.metadata.anomalous_version import AnomalousVersionAnalyzer, Versioning


def test_analyze_no_information(pypi_package_json: MagicMock) -> None:
"""Test for when there is no release information, so error"""
analyzer = AnomalisticVersionAnalyzer()
analyzer = AnomalousVersionAnalyzer()

pypi_package_json.get_releases.return_value = None

Expand All @@ -23,7 +23,7 @@ def test_analyze_no_information(pypi_package_json: MagicMock) -> None:

def test_analyze_invalid_time(pypi_package_json: MagicMock) -> None:
"""Test for when the supplied upload time does not conform with PEP 440, so error."""
analyzer = AnomalisticVersionAnalyzer()
analyzer = AnomalousVersionAnalyzer()
version = "1.1"
release = {
version: [
Expand Down Expand Up @@ -61,7 +61,7 @@ def test_analyze_invalid_time(pypi_package_json: MagicMock) -> None:

def test_analyze_no_time(pypi_package_json: MagicMock) -> None:
"""Test for when there is no supplied upload time, so error."""
analyzer = AnomalisticVersionAnalyzer()
analyzer = AnomalousVersionAnalyzer()
version = "1.1"
release = {
version: [
Expand Down Expand Up @@ -249,7 +249,7 @@ def test_analyze(
pypi_package_json: MagicMock, version: str, upload_date: str, result: HeuristicResult, versioning: str
) -> None:
"""
Generic test for the expected return value of the anomalistic version heuristic.
Generic test for the expected return value of the anomalous version heuristic.
Parameters
----------
Expand All @@ -262,7 +262,7 @@ def test_analyze(
versioning : str
which versioning system the heuristic should have identified.
"""
analyzer = AnomalisticVersionAnalyzer()
analyzer = AnomalousVersionAnalyzer()
release = {
version: [
{
Expand Down Expand Up @@ -292,7 +292,7 @@ def test_analyze(

pypi_package_json.get_releases.return_value = release
pypi_package_json.get_latest_version.return_value = version
expected_result: tuple[HeuristicResult, dict] = (result, {AnomalisticVersionAnalyzer.DETAIL_INFO_KEY: versioning})
expected_result: tuple[HeuristicResult, dict] = (result, {AnomalousVersionAnalyzer.DETAIL_INFO_KEY: versioning})

actual_result = analyzer.analyze(pypi_package_json)

Expand Down

0 comments on commit ad04616

Please sign in to comment.