feat(checks): New IAM Checks no full access to critical services (#2183)

This commit is contained in:
Gabriel Soltz
2023-04-12 07:47:21 +02:00
committed by GitHub
parent 9104d2e89e
commit 2f8a8988d7
8 changed files with 448 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
{
"Provider": "aws",
"CheckID": "iam_policy_no_full_access_to_cloudtrail",
"CheckTitle": "Ensure IAM policies that allow full \"cloudtrail:*\" privileges are not created",
"CheckType": [
"Software and Configuration Checks",
"Industry and Regulatory Standards",
"CIS AWS Foundations Benchmark"
],
"ServiceName": "iam",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "medium",
"ResourceType": "AwsIamPolicy",
"Description": "Ensure IAM policies that allow full \"cloudtrail:*\" privileges are not created",
"Risk": "CloudTrail is a critical service and IAM policies should follow least privilege model for this service in particular",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "It is more secure to start with a minimum set of permissions and grant additional permissions as necessary; rather than starting with permissions that are too lenient and then trying to tighten them later. List policies an analyze if permissions are the least possible to conduct business activities.",
"Url": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}

View File

@@ -0,0 +1,37 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
critical_service = "cloudtrail"
class iam_policy_no_full_access_to_cloudtrail(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.get("Arn")
report.resource_id = policy.get("PolicyName")
report.status = "PASS"
report.status_extended = f"Policy {policy.get('PolicyName')} does not allow '{critical_service}:*' privileges"
if policy.get("PolicyDocument"):
# Check the statements, if one includes critical_service:* stop iterating over the rest
if type(policy.get("PolicyDocument").get("Statement")) != list:
policy_statements = [policy.get("PolicyDocument").get("Statement")]
else:
policy_statements = policy.get("PolicyDocument").get("Statement")
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement.get("Effect") == "Allow"
and critical_service + ":*" in statement.get("Action")
and (
statement.get("Resource") == "*"
or statement.get("Resource") == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"Policy {policy.get('PolicyName')} allows '{critical_service}:*' privileges"
break
findings.append(report)
return findings

View File

@@ -0,0 +1,34 @@
{
"Provider": "aws",
"CheckID": "iam_policy_no_full_access_to_kms",
"CheckTitle": "Ensure IAM policies that allow full \"kms:*\" privileges are not created",
"CheckType": [
"Software and Configuration Checks",
"Industry and Regulatory Standards",
"CIS AWS Foundations Benchmark"
],
"ServiceName": "iam",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "medium",
"ResourceType": "AwsIamPolicy",
"Description": "Ensure IAM policies that allow full \"kms:*\" privileges are not created",
"Risk": "KMS is a critical service and IAM policies should follow least privilege model for this service in particular",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "It is more secure to start with a minimum set of permissions and grant additional permissions as necessary; rather than starting with permissions that are too lenient and then trying to tighten them later. List policies an analyze if permissions are the least possible to conduct business activities.",
"Url": "http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}

View File

@@ -0,0 +1,37 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
critical_service = "kms"
class iam_policy_no_full_access_to_kms(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies:
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.get("Arn")
report.resource_id = policy.get("PolicyName")
report.status = "PASS"
report.status_extended = f"Policy {policy.get('PolicyName')} does not allow '{critical_service}:*' privileges"
if policy.get("PolicyDocument"):
# Check the statements, if one includes critical_service:* stop iterating over the rest
if type(policy.get("PolicyDocument").get("Statement")) != list:
policy_statements = [policy.get("PolicyDocument").get("Statement")]
else:
policy_statements = policy.get("PolicyDocument").get("Statement")
for statement in policy_statements:
# Check policies with "Effect": "Allow" with "Action": "*" over "Resource": "*".
if (
statement.get("Effect") == "Allow"
and critical_service + ":*" in statement.get("Action")
and (
statement.get("Resource") == "*"
or statement.get("Resource") == ["*"]
)
):
report.status = "FAIL"
report.status_extended = f"Policy {policy.get('PolicyName')} allows '{critical_service}:*' privileges"
break
findings.append(report)
return findings