Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ the requirements that are currently supported by Macaron.
- If there is no commit, this check will fail.
* - ``mcn_scm_authenticity_check_1``
- **Source repo authenticity** - Check whether the claims of a source code repository made by a package can be corroborated.
- If the source code repository contains conflicting evidence regarding its claim of the source code repository, this check will fail. If no source code repository or corroborating evidence is found, or if the build system is unsupported, the check will return ``UNKNOWN`` as the result. This check currently supports only Maven artifacts.
- If the source code repository contains conflicting evidence regarding its claim of the source code repository, this check will fail. If no source code repository or corroborating evidence is found, or if the build system is unsupported, the check will return ``UNKNOWN`` as the result. This check supports Maven artifacts, and other artifacts that have a repository that is confirmed to be from a provenance file.
* - ``mcn_detect_malicious_metadata_1``
- **Malicious code detection** - Check whether the source code or package metadata has indicators of compromise.
- This check performs analysis on PyPI package metadata to detect malicious behavior. It also reports known malware from other ecosystems.
Expand Down
59 changes: 43 additions & 16 deletions src/macaron/slsa_analyzer/checks/scm_authenticity_check.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2024 - 2024, Oracle and/or its affiliates. All rights reserved.
# 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/.

"""A check to determine whether the source repository of a package can be independently verified."""
Expand Down Expand Up @@ -64,7 +64,7 @@ def __init__(self) -> None:
"Check whether the claims of a source repository provenance"
" made by a package can be corroborated."
" At this moment, this check only supports Maven packages"
" and returns UNKNOWN for others."
", or packages with a from-provenance repository, and returns UNKNOWN for others."
)

super().__init__(
Expand All @@ -85,16 +85,25 @@ def run_check(self, ctx: AnalyzeContext) -> CheckResultData:
CheckResultData
The result of the check.
"""
# Only support Maven at the moment.
# TODO: Add support for other systems.
if ctx.component.type != "maven":
provenance_repo_link = None
if provenance_info := ctx.dynamic_data["provenance_info"]:
provenance_repo_link = provenance_info.repository_url

# This check supports all Maven PURLs, and other PURLs only if they have a from-provenance repository URL.
# TODO: Add full support for other systems.
if ctx.component.type != "maven" and not provenance_repo_link:
return CheckResultData(result_tables=[], result_type=CheckResultType.UNKNOWN)

stars_count: int | None = None
fork_count: int | None = None
deps_dev_repo_info: dict | None = None

repo_link = ctx.component.repository.remote_path if ctx.component.repository else None
repo_link: str | None = None
if provenance_repo_link:
repo_link = str(provenance_repo_link)
elif ctx.component.repository:
repo_link = ctx.component.repository.remote_path

if repo_link:
deps_dev_repo_info = DepsDevRepoFinder.get_project_info(repo_link)

Expand All @@ -104,24 +113,42 @@ def run_check(self, ctx: AnalyzeContext) -> CheckResultData:

result_type = CheckResultType.UNKNOWN
result_tables: list[CheckFacts] = []
for verification_result in ctx.dynamic_data.get("repo_verification", []):
if not provenance_repo_link:
for verification_result in ctx.dynamic_data.get("repo_verification", []):
result_tables.append(
ScmAuthenticityFacts(
repo_link=repo_link,
reason=verification_result.reason,
status=verification_result.status.value,
build_tool=verification_result.build_tool.name,
confidence=Confidence.MEDIUM,
stars_count=stars_count,
fork_count=fork_count,
)
)

match (result_type, verification_result.status):
case (_, RepositoryVerificationStatus.PASSED):
result_type = CheckResultType.PASSED
case (CheckResultType.UNKNOWN, RepositoryVerificationStatus.FAILED):
result_type = CheckResultType.FAILED
else:
build_spec = ctx.dynamic_data["build_spec"]
build_tool = build_spec["tools"][0].name if build_spec["tools"] else "UNKNOWN"

result_tables.append(
ScmAuthenticityFacts(
repo_link=repo_link,
reason=verification_result.reason,
status=verification_result.status.value,
build_tool=verification_result.build_tool.name,
confidence=Confidence.MEDIUM,
reason="From provenance",
status=RepositoryVerificationStatus.PASSED,
build_tool=build_tool,
confidence=Confidence.HIGH,
stars_count=stars_count,
fork_count=fork_count,
)
)

match (result_type, verification_result.status):
case (_, RepositoryVerificationStatus.PASSED):
result_type = CheckResultType.PASSED
case (CheckResultType.UNKNOWN, RepositoryVerificationStatus.FAILED):
result_type = CheckResultType.FAILED
result_type = CheckResultType.PASSED

return CheckResultData(result_tables=result_tables, result_type=result_type)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ Policy("test_policy", component_id, "") :-
provenance(_, component_id, _, slsa_level, _, repo_url, commit_sha, _, asset_name, asset_url, _),
slsa_level = 2,
repo_url = "https://github.com/beeware/toga",
commit_sha = "ef1912b0a1b5c07793f9aa372409f5b9d36f2604".
commit_sha = "ef1912b0a1b5c07793f9aa372409f5b9d36f2604",
check_passed(component_id, "mcn_scm_authenticity_1").

apply_policy_to("test_policy", component_id) :-
is_component(component_id, "pkg:pypi/toga@0.5.1").
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.

description: |
Analyzing a PyPI PURL that has provenance available on the PyPI registry.
Analyzing a PyPI PURL that has provenance available on the PyPI registry, and passes the SCM authenticity check.

tags:
- macaron-python-package
Expand Down
Loading