diff --git a/prowler/lib/check/models.py b/prowler/lib/check/models.py
index 71c6e35487..8b4acf5733 100644
--- a/prowler/lib/check/models.py
+++ b/prowler/lib/check/models.py
@@ -505,7 +505,7 @@ def load_check_metadata(metadata_file: str) -> CheckMetadata:
@dataclass
-class Check_Report_GitHub(Check_Report):
+class Check_Report_Github(Check_Report):
"""Contains the GitHub Check's finding information."""
account_name: str
diff --git a/prowler/lib/outputs/finding.py b/prowler/lib/outputs/finding.py
index 9867111765..423460c16f 100644
--- a/prowler/lib/outputs/finding.py
+++ b/prowler/lib/outputs/finding.py
@@ -232,6 +232,14 @@ class Finding(BaseModel):
)
output_data["region"] = f"namespace: {check_output.namespace}"
+ elif provider.type == "github":
+ output_data["auth_method"] = provider.auth_method
+ output_data["resource_name"] = check_output.resource_name
+ output_data["resource_uid"] = check_output.resource_id
+ output_data["account_name"] = provider.identity.account_name
+ output_data["account_uid"] = provider.identity.account_id
+ output_data["region"] = "global"
+
# check_output Unique ID
# TODO: move this to a function
# TODO: in Azure, GCP and K8s there are fidings without resource_name
diff --git a/prowler/lib/outputs/html/html.py b/prowler/lib/outputs/html/html.py
index 5d5c471593..5263f13f1f 100644
--- a/prowler/lib/outputs/html/html.py
+++ b/prowler/lib/outputs/html/html.py
@@ -538,6 +538,51 @@ class HTML(Output):
)
return ""
+ @staticmethod
+ def get_github_assessment_summary(provider: Provider) -> str:
+ """
+ get_github_assessment_summary gets the HTML assessment summary for the provider
+
+ Args:
+ provider (Provider): the provider object
+
+ Returns:
+ str: the HTML assessment summary
+ """
+ try:
+ return f"""
+
+
+
+
+ -
+ GitHub account: {provider.identity.account_name}
+
+
+
+
+
+
+
+
+ -
+ GitHub authentication method: {provider.auth_method}
+
+
+
+
"""
+ except Exception as error:
+ logger.error(
+ f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}] -- {error}"
+ )
+ return ""
+
@staticmethod
def get_assessment_summary(provider: Provider) -> str:
"""
diff --git a/prowler/providers/github/github_provider.py b/prowler/providers/github/github_provider.py
index 3b2b0ad143..953d78f43c 100644
--- a/prowler/providers/github/github_provider.py
+++ b/prowler/providers/github/github_provider.py
@@ -17,6 +17,7 @@ from prowler.providers.github.models import GithubIdentityInfo, GithubSession
class GithubProvider(Provider):
_type: str = "github"
+ _auth_method: str
_session: GithubSession
_identity: GithubIdentityInfo
_audit_config: dict
@@ -81,15 +82,20 @@ class GithubProvider(Provider):
Provider.set_global_provider(self)
@property
- def identity(self):
- """Returns the identity information for the GitHub provider."""
- return self._identity
+ def auth_method(self):
+ """Returns the authentication method for the GitHub provider."""
+ return self._auth_method
@property
def session(self):
"""Returns the session object for the GitHub provider."""
return self._session
+ @property
+ def identity(self):
+ """Returns the identity information for the GitHub provider."""
+ return self._identity
+
@property
def type(self):
"""Returns the type of the GitHub provider."""
@@ -130,10 +136,13 @@ class GithubProvider(Provider):
if personal_access_token:
session_token = getenv("GITHUB_PERSONAL_ACCESS_TOKEN")
+ self._auth_method = "personal_access_token"
elif github_app:
session_token = getenv("GITHUB_APP_TOKEN")
+ self._auth_method = "github_app"
elif oauth_app:
session_token = getenv("GITHUB_OAUTH_TOKEN")
+ self._auth_method = "oauth_app"
else:
raise ValueError(
"A GitHub API token of some kind is required to initialize GitHub provider."
@@ -175,4 +184,4 @@ class GithubProvider(Provider):
return identity
def print_credentials(self):
- print("Using GitHub PAT")
+ print(f"You are using a {self.auth_method} as authentication method.")
diff --git a/prowler/providers/github/lib/mutelist/mutelist.py b/prowler/providers/github/lib/mutelist/mutelist.py
index 31ec3b1b8d..ba1ed7a56e 100644
--- a/prowler/providers/github/lib/mutelist/mutelist.py
+++ b/prowler/providers/github/lib/mutelist/mutelist.py
@@ -1,4 +1,4 @@
-from prowler.lib.check.models import Check_Report_GitHub
+from prowler.lib.check.models import Check_Report_Github
from prowler.lib.mutelist.mutelist import Mutelist
from prowler.lib.outputs.utils import unroll_dict, unroll_tags
@@ -6,7 +6,7 @@ from prowler.lib.outputs.utils import unroll_dict, unroll_tags
class GitHubMutelist(Mutelist):
def is_finding_muted(
self,
- finding: Check_Report_GitHub,
+ finding: Check_Report_Github,
) -> bool:
return self.is_muted(
finding.account_name,
diff --git a/prowler/providers/github/lib/service/service.py b/prowler/providers/github/lib/service/service.py
index e113e5a480..43ae18a1d4 100644
--- a/prowler/providers/github/lib/service/service.py
+++ b/prowler/providers/github/lib/service/service.py
@@ -11,9 +11,7 @@ class GithubService:
provider: GithubProvider,
):
self.client = self.__set_client__(
- provider.identity,
provider.session,
- service,
)
self.audit_config = provider.audit_config
diff --git a/prowler/providers/github/services/repository/repository_client.py b/prowler/providers/github/services/repository/repository_client.py
index 232f8ddf81..3ea47cb952 100644
--- a/prowler/providers/github/services/repository/repository_client.py
+++ b/prowler/providers/github/services/repository/repository_client.py
@@ -1,4 +1,4 @@
from prowler.providers.common.provider import Provider
-from prowler.providers.github.services.repository.repository_client import Repository
+from prowler.providers.github.services.repository.repository_service import Repository
repository_client = Repository(Provider.get_global_provider())
diff --git a/prowler/providers/github/services/repository/repository_public_has_securitymd_file/repository_public_has_securitymd_file.metadata.json b/prowler/providers/github/services/repository/repository_public_has_securitymd_file/repository_public_has_securitymd_file.metadata.json
new file mode 100644
index 0000000000..490c417dc4
--- /dev/null
+++ b/prowler/providers/github/services/repository/repository_public_has_securitymd_file/repository_public_has_securitymd_file.metadata.json
@@ -0,0 +1,32 @@
+{
+ "Provider": "github",
+ "CheckID": "repository_public_has_securitymd_file",
+ "CheckTitle": "Check if public repositories have a SECURITY.md file",
+ "CheckType": [
+ "CIS GitHub Benchmark v1.0.0"
+ ],
+ "ServiceName": "repository",
+ "SubServiceName": "",
+ "ResourceIdTemplate": "github:user-id:repository/repository-name",
+ "Severity": "low",
+ "ResourceType": "Other",
+ "Description": "Ensure that public repositories have a SECURITY.md file",
+ "Risk": "Not having a SECURITY.md file in a public repository may lead to security vulnerabilities being overlooked by users and contributors.",
+ "RelatedUrl": "https://gist.github.com/bayudwiyansatria/3aa6a865aad8d45d69cdb80090bea7c7",
+ "Remediation": {
+ "Code": {
+ "CLI": "",
+ "NativeIaC": "",
+ "Other": "",
+ "Terraform": ""
+ },
+ "Recommendation": {
+ "Text": "Add a SECURITY.md file to the root of the repository. The file should contain information on how to report a security vulnerability, the security policy of the repository, and any other relevant information.",
+ "Url": "https://github.blog/changelog/2019-05-23-security-policy/"
+ }
+ },
+ "Categories": [],
+ "DependsOn": [],
+ "RelatedTo": [],
+ "Notes": ""
+}
diff --git a/prowler/providers/github/services/repository/repository_public_has_securitymd_file/repository_public_has_securitymd_file.py b/prowler/providers/github/services/repository/repository_public_has_securitymd_file/repository_public_has_securitymd_file.py
new file mode 100644
index 0000000000..bb55aa72b1
--- /dev/null
+++ b/prowler/providers/github/services/repository/repository_public_has_securitymd_file/repository_public_has_securitymd_file.py
@@ -0,0 +1,42 @@
+from typing import List
+
+from prowler.lib.check.models import Check, Check_Report_Github
+from prowler.providers.github.services.repository.repository_client import (
+ repository_client,
+)
+
+
+class repository_public_has_securitymd_file(Check):
+ """Check if a public repository has a SECURITY.md file
+
+ This class verifies wheter each public repository has a SECURITY.md file.
+ """
+
+ def execute(self) -> List[Check_Report_Github]:
+ """Execute the Github Repository Public Has Securitymd File check
+
+ Iterates over all public repositories and checks if they have a SECURITY.md file.
+
+ Returns:
+ List[Check_Report_Github]: A list of reports for each repository
+ """
+ findings = []
+ for repo in repository_client.repositories.values():
+ report = Check_Report_Github(self.metadata())
+ report.resource_id = repo.id
+ report.resource_name = repo.name
+ report.status = "PASS"
+ report.status_extended = (
+ f"Repository {repo.name} does have a SECURITY.md file."
+ )
+
+ if not repo.private:
+ if not repo.securitymd:
+ report.status = "FAIL"
+ report.status_extended = (
+ f"Repository {repo.name} does not have a SECURITY.md file."
+ )
+
+ findings.append(report)
+
+ return findings
diff --git a/prowler/providers/github/services/repository/repository_service.py b/prowler/providers/github/services/repository/repository_service.py
index 8292702ab4..6566058c70 100644
--- a/prowler/providers/github/services/repository/repository_service.py
+++ b/prowler/providers/github/services/repository/repository_service.py
@@ -10,19 +10,22 @@ class Repository(GithubService):
def __init__(self, provider):
super().__init__(__class__.__name__, provider)
self.repositories = {}
- self.__threading_call__(self._list_repositories)
+ self._list_repositories()
def _list_repositories(self):
logger.info("Repository - Listing Repositories...")
try:
for repo in self.client.get_user().get_repos():
+ try:
+ securitymd_exists = repo.get_contents("SECURITY.md") is not None
+ except Exception:
+ securitymd_exists = False
self.repositories[repo.id] = Repo(
id=repo.id,
name=repo.name,
full_name=repo.full_name,
private=repo.private,
- description=repo.description,
- securitymd=repo.get_contents("SECURITY.md") is not None,
+ securitymd=securitymd_exists,
)
except Exception as error:
logger.error(
@@ -40,5 +43,4 @@ class Repo(BaseModel):
name: str
full_name: str
private: bool
- description: Optional[str]
securitymd: Optional[bool] = False