Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(iam): add new check iam_policy_no_kms_decryption_actions #5619

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"Provider": "aws",
"CheckID": "iam_policy_no_kms_decryption_actions",
"CheckTitle": "Check if IAM customer managed policies",
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices/CIS AWS Foundations Benchmark"
],
"ServiceName": "iam",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:iam::{account-id}:{resource-type}/{resource-id}",
"Severity": "medium",
"ResourceType": "AwsIamPolicy",
"Description": "Ensure IAM customer managed policies do not allow broad decryption permissions (kms:Decrypt or kms:ReEncryptFrom) on all AWS KMS keys",
"Risk": "Allowing broad decryption permissions (kms:Decrypt or kms:ReEncryptFrom) on all AWS KMS keys can lead to unauthorized data access, especially if users inadvertently or maliciously decrypt sensitive information.",
"RelatedUrl": "https://docs.aws.amazon.com/kms/latest/developerguide/iam-policies.html",
"Remediation": {
"Code": {
"CLI": "aws iam update-policy --policy-arn <policy-arn> --policy-document '{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Action\": [ \"kms:Decrypt\", \"kms:ReEncryptFrom\" ], \"Resource\": \"arn:aws:kms:<region>:<account-id>:key/<key-id>\" } ] }'",
"NativeIaC": "",
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/kms-controls.html#kms-1",
"Terraform": ""
},
"Recommendation": {
"Text": "Restrict decryption actions in IAM customer managed policies to specific KMS keys rather than allowing permissions on all keys. By specifying particular key ARNs in the Resource field, you limit the keys that identities can decrypt, enhancing control and compliance with best practices in data security.",
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-edit.html#edit-managed-policy-console"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from typing import List

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_kms_decryption_actions(Check):
"""Check IAM policies for KMS decryption actions.

This class verifies that IAM policies do not allow KMS decryption actions (kms:Decrypt or kms:ReEncryptFrom) on all resources.
"""

def execute(self) -> List[Check_Report_AWS]:
"""Execute the No KMS Decryption Actions check.

Iterates over all IAM policies and checks if any of them allow KMS decryption actions.

Returns:
List[Check_Report_AWS]: A list of reports for each IAM policy that allows KMS decryption actions.
"""
findings = []
for policy in iam_client.policies:
# Check only custom policies
if policy.type == "Custom":
report = Check_Report_AWS(self.metadata())
report.region = iam_client.region
report.resource_arn = policy.arn
report.resource_id = policy.name
report.resource_tags = policy.tags
report.status = "PASS"
report.status_extended = f"Custom Policy {policy.name} does not allow kms:Decrypt or kms:ReEncryptFrom privileges on all resources."

if policy.document:
for statement in policy.document.get("Statement", []):
if (
statement.get("Effect") == "Allow"
and "Action" in statement
and (
"kms:Decrypt" in statement["Action"]
or "kms:ReEncryptFrom" in statement["Action"]
)
and "Resource" in statement
and "*" in statement["Resource"]
):
report.status = "FAIL"
report.status_extended = f"Custom Policy {policy.name} does allow kms:Decrypt or kms:ReEncryptFrom privileges on all resources."

findings.append(report)

return findings
19 changes: 9 additions & 10 deletions prowler/providers/aws/services/kms/kms_service.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import json
from typing import Optional
from typing import Dict, List, Optional

from pydantic import BaseModel
from pydantic import BaseModel, Field

from prowler.lib.logger import logger
from prowler.lib.scan_filters.scan_filters import is_resource_filtered
from prowler.providers.aws.lib.service.service import AWSService


################## KMS
class KMS(AWSService):
def __init__(self, provider):
# Call AWSService's __init__
Expand Down Expand Up @@ -115,11 +114,11 @@ def _list_resource_tags(self):
class Key(BaseModel):
id: str
arn: str
state: Optional[str]
origin: Optional[str]
manager: Optional[str]
rotation_enabled: Optional[bool]
policy: Optional[dict]
spec: Optional[str]
state: Optional[str] = None
origin: Optional[str] = None
manager: Optional[str] = None
rotation_enabled: Optional[bool] = None
policy: Optional[Dict] = None
spec: Optional[str] = None
region: str
tags: Optional[list] = []
tags: List[Dict[str, str]] = Field(default_factory=list)
Loading