mirror of
https://github.com/prowler-cloud/prowler.git
synced 2025-12-19 05:17:47 +00:00
feat(aws): new check bedrock_api_key_no_long_term_credentials (#8396)
This commit is contained in:
16
poetry.lock
generated
16
poetry.lock
generated
@@ -883,18 +883,18 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "boto3"
|
||||
version = "1.39.14"
|
||||
version = "1.39.15"
|
||||
description = "The AWS SDK for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main", "dev"]
|
||||
files = [
|
||||
{file = "boto3-1.39.14-py3-none-any.whl", hash = "sha256:82c6868cad18c3bd4170915e9525f9af5f83e9779c528417f8863629558fc2d0"},
|
||||
{file = "boto3-1.39.14.tar.gz", hash = "sha256:fabb16360a93b449d5241006485bcc761c26694e75ac01009f4459f114acc06e"},
|
||||
{file = "boto3-1.39.15-py3-none-any.whl", hash = "sha256:38fc54576b925af0075636752de9974e172c8a2cf7133400e3e09b150d20fb6a"},
|
||||
{file = "boto3-1.39.15.tar.gz", hash = "sha256:b4483625f0d8c35045254dee46cd3c851bbc0450814f20b9b25bee1b5c0d8409"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
botocore = ">=1.39.14,<1.40.0"
|
||||
botocore = ">=1.39.15,<1.40.0"
|
||||
jmespath = ">=0.7.1,<2.0.0"
|
||||
s3transfer = ">=0.13.0,<0.14.0"
|
||||
|
||||
@@ -903,14 +903,14 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
|
||||
|
||||
[[package]]
|
||||
name = "botocore"
|
||||
version = "1.39.14"
|
||||
version = "1.39.15"
|
||||
description = "Low-level, data-driven core of boto 3."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main", "dev"]
|
||||
files = [
|
||||
{file = "botocore-1.39.14-py3-none-any.whl", hash = "sha256:4ed551c77194167b7e8063f33059bc2f9b2ead0ed4ee33dc7857273648ed4349"},
|
||||
{file = "botocore-1.39.14.tar.gz", hash = "sha256:7fc44d4ad13b524e5d8a6296785776ef5898ac026ff74df9b35313831d507926"},
|
||||
{file = "botocore-1.39.15-py3-none-any.whl", hash = "sha256:eb9cfe918ebfbfb8654e1b153b29f0c129d586d2c0d7fb4032731d49baf04cff"},
|
||||
{file = "botocore-1.39.15.tar.gz", hash = "sha256:2aa29a717f14f8c7ca058c2e297aaed0aa10ecea24b91514eee802814d1b7600"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -5839,4 +5839,4 @@ type = ["pytest-mypy"]
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = ">3.9.1,<3.13"
|
||||
content-hash = "d50d5af2208d667091b3873ca93da8feafa13e455e412fc7713f0e73e83595e3"
|
||||
content-hash = "a0635a7bb99427a5169b126b429d603079fc24c39ce6759a648fdffe74e50d6c"
|
||||
|
||||
@@ -6,6 +6,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
|
||||
### Added
|
||||
- `bedrock_api_key_no_administrative_privileges` check for AWS provider [(#8321)](https://github.com/prowler-cloud/prowler/pull/8321)
|
||||
- `bedrock_api_key_no_long_term_credentials` check for AWS provider [(#8396)](https://github.com/prowler-cloud/prowler/pull/8396)
|
||||
- Support App Key Content in GitHub provider [(#8271)](https://github.com/prowler-cloud/prowler/pull/8271)
|
||||
- CIS 4.0 for the Azure provider [(#7782)](https://github.com/prowler-cloud/prowler/pull/7782)
|
||||
- `vm_desired_sku_size` check for Azure provider [(#8191)](https://github.com/prowler-cloud/prowler/pull/8191)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "bedrock_api_key_no_long_term_credentials",
|
||||
"CheckTitle": "Ensure Amazon Bedrock API keys are not long-term credentials",
|
||||
"CheckType": [
|
||||
"Software and Configuration Checks",
|
||||
"Industry and Regulatory Standards"
|
||||
],
|
||||
"ServiceName": "bedrock",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:iam:region:account-id:user/{user-name}/credential/{api-key-id}",
|
||||
"Severity": "high",
|
||||
"ResourceType": "AwsIamServiceSpecificCredential",
|
||||
"Description": "Ensure that Amazon Bedrock API keys have expiration dates set to prevent long-term credential exposure. Long-term credentials pose a significant security risk as they remain valid indefinitely and can be used for unauthorized access if compromised.",
|
||||
"Risk": "Amazon Bedrock API keys without expiration dates are long-term credentials that remain valid indefinitely. This increases the risk of unauthorized access if the credentials are compromised, as they cannot be automatically invalidated. Long-term credentials violate the principle of credential rotation and can lead to security vulnerabilities, data breaches, or unauthorized usage of Bedrock services.",
|
||||
"RelatedUrl": "https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws iam delete-service-specific-credential --user-name <username> --service-specific-credential-id <credential-id>",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Delete the long-term API keys for Amazon Bedrock. Instead, use temporary credentials, IAM roles, or create new API keys with appropriate expiration dates. Implement a credential rotation policy to ensure all API keys have reasonable expiration periods. Consider using AWS STS for temporary credentials when possible.",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"gen-ai",
|
||||
"trustboundaries"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "This check verifies that Amazon Bedrock API keys have expiration dates set. API keys without expiration dates are considered long-term credentials and pose a security risk. The check follows security best practices for credential management and the principle of least privilege."
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from prowler.lib.check.models import Check, Check_Report_AWS
|
||||
from prowler.providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class bedrock_api_key_no_long_term_credentials(Check):
|
||||
"""
|
||||
Bedrock API keys should be short-lived to reduce the risk of unauthorized access.
|
||||
This check verifies if there are any long-term Bedrock API keys.
|
||||
If there are, it checks if they are expired or will be expired.
|
||||
If they are expired, it will be marked as PASS.
|
||||
If they are not expired, it will be marked as FAIL and the severity will be critical if the key will never expire.
|
||||
"""
|
||||
|
||||
def execute(self):
|
||||
"""
|
||||
Execute the Bedrock API key no long-term credentials check.
|
||||
|
||||
Iterate over all the Bedrock API keys and check if they are expired or will be expired.
|
||||
|
||||
Returns:
|
||||
List[Check_Report_AWS]: A list of report objects with the results of the check.
|
||||
"""
|
||||
|
||||
findings = []
|
||||
for api_key in iam_client.service_specific_credentials:
|
||||
if api_key.service_name != "bedrock.amazonaws.com":
|
||||
continue
|
||||
if api_key.expiration_date:
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource=api_key)
|
||||
# Check if the expiration date is in the future
|
||||
if api_key.expiration_date > datetime.now(timezone.utc):
|
||||
report.status = "FAIL"
|
||||
# Get the days until the expiration date
|
||||
days_until_expiration = (
|
||||
api_key.expiration_date - datetime.now(timezone.utc)
|
||||
).days
|
||||
if days_until_expiration > 10000:
|
||||
self.Severity = "critical"
|
||||
report.status_extended = f"Long-term Bedrock API key {api_key.id} in user {api_key.user.name} exists and never expires."
|
||||
else:
|
||||
report.status_extended = f"Long-term Bedrock API key {api_key.id} in user {api_key.user.name} exists and will expire in {days_until_expiration} days."
|
||||
else:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Long-term Bedrock API key {api_key.id} in user {api_key.user.name} exists but has expired."
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -36,8 +36,8 @@ dependencies = [
|
||||
"azure-mgmt-subscription==3.1.1",
|
||||
"azure-mgmt-web==8.0.0",
|
||||
"azure-storage-blob==12.24.1",
|
||||
"boto3==1.39.14",
|
||||
"botocore==1.39.14",
|
||||
"boto3==1.39.15",
|
||||
"botocore==1.39.15",
|
||||
"colorama==0.4.6",
|
||||
"cryptography==44.0.1",
|
||||
"dash==3.1.1",
|
||||
|
||||
@@ -842,7 +842,7 @@ aws:
|
||||
aws_provider = AwsProvider()
|
||||
response = aws_provider.generate_regional_clients("ec2")
|
||||
|
||||
assert len(response.keys()) == 32
|
||||
assert len(response.keys()) == 33
|
||||
|
||||
@mock_aws
|
||||
def test_generate_regional_clients_with_enabled_regions(self):
|
||||
|
||||
@@ -0,0 +1,468 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from unittest import mock
|
||||
|
||||
from moto import mock_aws
|
||||
|
||||
from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider
|
||||
|
||||
|
||||
class Test_bedrock_api_key_no_long_term_credentials:
|
||||
@mock_aws
|
||||
def test_no_bedrock_api_keys(self):
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials import (
|
||||
bedrock_api_key_no_long_term_credentials,
|
||||
)
|
||||
|
||||
check = bedrock_api_key_no_long_term_credentials()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_bedrock_api_key_with_future_expiration_date(self):
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
# Mock service-specific credentials
|
||||
from prowler.providers.aws.services.iam.iam_service import (
|
||||
ServiceSpecificCredential,
|
||||
User,
|
||||
)
|
||||
|
||||
# Create a mock user
|
||||
mock_user = User(
|
||||
name="test_user",
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user",
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
|
||||
# Create a mock service-specific credential with future expiration date
|
||||
expiration_date = datetime.now(timezone.utc) + timedelta(days=30)
|
||||
mock_credential = ServiceSpecificCredential(
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user/credential/test-credential-id",
|
||||
user=mock_user,
|
||||
status="Active",
|
||||
create_date=datetime.now(timezone.utc),
|
||||
service_user_name=None,
|
||||
service_credential_alias=None,
|
||||
expiration_date=expiration_date,
|
||||
id="test-credential-id",
|
||||
service_name="bedrock.amazonaws.com",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
)
|
||||
|
||||
iam.service_specific_credentials = [mock_credential]
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials.iam_client",
|
||||
new=iam,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials import (
|
||||
bedrock_api_key_no_long_term_credentials,
|
||||
)
|
||||
|
||||
check = bedrock_api_key_no_long_term_credentials()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert "will expire in" in result[0].status_extended
|
||||
assert "test-credential-id" in result[0].status_extended
|
||||
assert "test_user" in result[0].status_extended
|
||||
assert result[0].resource_id == "test-credential-id"
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
|
||||
@mock_aws
|
||||
def test_bedrock_api_key_with_critical_expiration_date(self):
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
# Mock service-specific credentials
|
||||
from prowler.providers.aws.services.iam.iam_service import (
|
||||
ServiceSpecificCredential,
|
||||
User,
|
||||
)
|
||||
|
||||
# Create a mock user
|
||||
mock_user = User(
|
||||
name="test_user",
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user",
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
|
||||
# Create a mock service-specific credential with very far future expiration date (>10000 days)
|
||||
expiration_date = datetime.now(timezone.utc) + timedelta(days=15000)
|
||||
mock_credential = ServiceSpecificCredential(
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user/credential/test-credential-id",
|
||||
user=mock_user,
|
||||
status="Active",
|
||||
create_date=datetime.now(timezone.utc),
|
||||
service_user_name=None,
|
||||
service_credential_alias=None,
|
||||
expiration_date=expiration_date,
|
||||
id="test-credential-id",
|
||||
service_name="bedrock.amazonaws.com",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
)
|
||||
|
||||
iam.service_specific_credentials = [mock_credential]
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials.iam_client",
|
||||
new=iam,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials import (
|
||||
bedrock_api_key_no_long_term_credentials,
|
||||
)
|
||||
|
||||
check = bedrock_api_key_no_long_term_credentials()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert "never expires" in result[0].status_extended
|
||||
assert "test-credential-id" in result[0].status_extended
|
||||
assert "test_user" in result[0].status_extended
|
||||
assert result[0].resource_id == "test-credential-id"
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert check.Severity == "critical"
|
||||
|
||||
@mock_aws
|
||||
def test_bedrock_api_key_with_expired_date(self):
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
# Mock service-specific credentials
|
||||
from prowler.providers.aws.services.iam.iam_service import (
|
||||
ServiceSpecificCredential,
|
||||
User,
|
||||
)
|
||||
|
||||
# Create a mock user
|
||||
mock_user = User(
|
||||
name="test_user",
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user",
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
|
||||
# Create a mock service-specific credential with past expiration date
|
||||
expiration_date = datetime.now(timezone.utc) - timedelta(days=30)
|
||||
mock_credential = ServiceSpecificCredential(
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user/credential/test-credential-id",
|
||||
user=mock_user,
|
||||
status="Active",
|
||||
create_date=datetime.now(timezone.utc),
|
||||
service_user_name=None,
|
||||
service_credential_alias=None,
|
||||
expiration_date=expiration_date,
|
||||
id="test-credential-id",
|
||||
service_name="bedrock.amazonaws.com",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
)
|
||||
|
||||
iam.service_specific_credentials = [mock_credential]
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials.iam_client",
|
||||
new=iam,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials import (
|
||||
bedrock_api_key_no_long_term_credentials,
|
||||
)
|
||||
|
||||
check = bedrock_api_key_no_long_term_credentials()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert "has expired" in result[0].status_extended
|
||||
assert "test-credential-id" in result[0].status_extended
|
||||
assert "test_user" in result[0].status_extended
|
||||
assert result[0].resource_id == "test-credential-id"
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
|
||||
@mock_aws
|
||||
def test_bedrock_api_key_without_expiration_date_ignored(self):
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
# Mock service-specific credentials
|
||||
from prowler.providers.aws.services.iam.iam_service import (
|
||||
ServiceSpecificCredential,
|
||||
User,
|
||||
)
|
||||
|
||||
# Create a mock user
|
||||
mock_user = User(
|
||||
name="test_user",
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user",
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
|
||||
# Create a mock service-specific credential without expiration date (should be ignored)
|
||||
mock_credential = ServiceSpecificCredential(
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user/credential/test-credential-id",
|
||||
user=mock_user,
|
||||
status="Active",
|
||||
create_date=datetime.now(timezone.utc),
|
||||
service_user_name=None,
|
||||
service_credential_alias=None,
|
||||
expiration_date=None, # No expiration date - should be ignored
|
||||
id="test-credential-id",
|
||||
service_name="bedrock.amazonaws.com",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
)
|
||||
|
||||
iam.service_specific_credentials = [mock_credential]
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials.iam_client",
|
||||
new=iam,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials import (
|
||||
bedrock_api_key_no_long_term_credentials,
|
||||
)
|
||||
|
||||
check = bedrock_api_key_no_long_term_credentials()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_non_bedrock_api_key_ignored(self):
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
# Mock service-specific credentials
|
||||
from prowler.providers.aws.services.iam.iam_service import (
|
||||
ServiceSpecificCredential,
|
||||
User,
|
||||
)
|
||||
|
||||
# Create a mock user
|
||||
mock_user = User(
|
||||
name="test_user",
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user",
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
|
||||
# Create a mock service-specific credential for a different service
|
||||
expiration_date = datetime.now(timezone.utc) + timedelta(days=30)
|
||||
mock_credential = ServiceSpecificCredential(
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user/credential/test-credential-id",
|
||||
user=mock_user,
|
||||
status="Active",
|
||||
create_date=datetime.now(timezone.utc),
|
||||
service_user_name=None,
|
||||
service_credential_alias=None,
|
||||
expiration_date=expiration_date,
|
||||
id="test-credential-id",
|
||||
service_name="codecommit.amazonaws.com", # Different service
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
)
|
||||
|
||||
iam.service_specific_credentials = [mock_credential]
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials.iam_client",
|
||||
new=iam,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials import (
|
||||
bedrock_api_key_no_long_term_credentials,
|
||||
)
|
||||
|
||||
check = bedrock_api_key_no_long_term_credentials()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_multiple_bedrock_api_keys_mixed_scenarios(self):
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
iam = IAM(aws_provider)
|
||||
|
||||
# Mock service-specific credentials
|
||||
from prowler.providers.aws.services.iam.iam_service import (
|
||||
ServiceSpecificCredential,
|
||||
User,
|
||||
)
|
||||
|
||||
# Create mock users
|
||||
mock_user1 = User(
|
||||
name="test_user1",
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user1",
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
|
||||
mock_user2 = User(
|
||||
name="test_user2",
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user2",
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
|
||||
mock_user3 = User(
|
||||
name="test_user3",
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user3",
|
||||
attached_policies=[],
|
||||
inline_policies=[],
|
||||
)
|
||||
|
||||
# Create a mock service-specific credential with future expiration date
|
||||
expiration_date1 = datetime.now(timezone.utc) + timedelta(days=30)
|
||||
mock_credential1 = ServiceSpecificCredential(
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user1/credential/test-credential-id-1",
|
||||
user=mock_user1,
|
||||
status="Active",
|
||||
create_date=datetime.now(timezone.utc),
|
||||
service_user_name=None,
|
||||
service_credential_alias=None,
|
||||
expiration_date=expiration_date1,
|
||||
id="test-credential-id-1",
|
||||
service_name="bedrock.amazonaws.com",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
)
|
||||
|
||||
# Create a mock service-specific credential with critical expiration date
|
||||
expiration_date2 = datetime.now(timezone.utc) + timedelta(days=15000)
|
||||
mock_credential2 = ServiceSpecificCredential(
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user2/credential/test-credential-id-2",
|
||||
user=mock_user2,
|
||||
status="Active",
|
||||
create_date=datetime.now(timezone.utc),
|
||||
service_user_name=None,
|
||||
service_credential_alias=None,
|
||||
expiration_date=expiration_date2,
|
||||
id="test-credential-id-2",
|
||||
service_name="bedrock.amazonaws.com",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
)
|
||||
|
||||
# Create a mock service-specific credential with expired date
|
||||
expiration_date3 = datetime.now(timezone.utc) - timedelta(days=30)
|
||||
mock_credential3 = ServiceSpecificCredential(
|
||||
arn=f"arn:aws:iam:{AWS_REGION_US_EAST_1}:123456789012:user/test_user3/credential/test-credential-id-3",
|
||||
user=mock_user3,
|
||||
status="Active",
|
||||
create_date=datetime.now(timezone.utc),
|
||||
service_user_name=None,
|
||||
service_credential_alias=None,
|
||||
expiration_date=expiration_date3,
|
||||
id="test-credential-id-3",
|
||||
service_name="bedrock.amazonaws.com",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
)
|
||||
|
||||
iam.service_specific_credentials = [
|
||||
mock_credential1,
|
||||
mock_credential2,
|
||||
mock_credential3,
|
||||
]
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials.iam_client",
|
||||
new=iam,
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.bedrock.bedrock_api_key_no_long_term_credentials.bedrock_api_key_no_long_term_credentials import (
|
||||
bedrock_api_key_no_long_term_credentials,
|
||||
)
|
||||
|
||||
check = bedrock_api_key_no_long_term_credentials()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 3
|
||||
|
||||
# Check the credential with future expiration date (FAIL)
|
||||
fail_result1 = next(
|
||||
r for r in result if r.resource_id == "test-credential-id-1"
|
||||
)
|
||||
assert fail_result1.status == "FAIL"
|
||||
assert "will expire in" in fail_result1.status_extended
|
||||
assert "test-credential-id-1" in fail_result1.status_extended
|
||||
assert "test_user1" in fail_result1.status_extended
|
||||
|
||||
# Check the credential with critical expiration date (FAIL)
|
||||
fail_result2 = next(
|
||||
r for r in result if r.resource_id == "test-credential-id-2"
|
||||
)
|
||||
assert fail_result2.status == "FAIL"
|
||||
assert "never expires" in fail_result2.status_extended
|
||||
assert "test-credential-id-2" in fail_result2.status_extended
|
||||
assert "test_user2" in fail_result2.status_extended
|
||||
|
||||
# Check the credential with expired date (PASS)
|
||||
pass_result = next(
|
||||
r for r in result if r.resource_id == "test-credential-id-3"
|
||||
)
|
||||
assert pass_result.status == "PASS"
|
||||
assert "has expired" in pass_result.status_extended
|
||||
assert "test-credential-id-3" in pass_result.status_extended
|
||||
assert "test_user3" in pass_result.status_extended
|
||||
@@ -106,9 +106,6 @@ class Test_DynamoDB_Service:
|
||||
{"AttributeName": "app", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
Tags=[
|
||||
{"Key": "test", "Value": "test"},
|
||||
],
|
||||
DeletionProtectionEnabled=True,
|
||||
)["TableDescription"]
|
||||
# DynamoDB client for this test class
|
||||
@@ -119,9 +116,6 @@ class Test_DynamoDB_Service:
|
||||
assert tables_arn == table["TableArn"]
|
||||
assert tables.name == "test1"
|
||||
assert tables.region == AWS_REGION_US_EAST_1
|
||||
assert tables.tags == [
|
||||
{"Key": "test", "Value": "test"},
|
||||
]
|
||||
assert tables.billing_mode == "PAY_PER_REQUEST"
|
||||
assert tables.deletion_protection
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ class Test_EventBridge_Service:
|
||||
)
|
||||
aws_provider = set_mocked_aws_provider()
|
||||
eventbridge = EventBridge(aws_provider)
|
||||
assert len(eventbridge.buses) == 33 # 1 per region
|
||||
assert len(eventbridge.buses) == 34 # 1 per region
|
||||
for bus in eventbridge.buses.values():
|
||||
if bus.name == "test":
|
||||
assert (
|
||||
|
||||
@@ -63,7 +63,7 @@ class Test_guardduty_is_enabled:
|
||||
|
||||
check = guardduty_is_enabled()
|
||||
results = check.execute()
|
||||
assert len(results) == 29
|
||||
assert len(results) == 32
|
||||
for result in results:
|
||||
if result.region == AWS_REGION_EU_WEST_1:
|
||||
assert result.status == "PASS"
|
||||
@@ -108,7 +108,7 @@ class Test_guardduty_is_enabled:
|
||||
|
||||
check = guardduty_is_enabled()
|
||||
results = check.execute()
|
||||
assert len(results) == 29
|
||||
assert len(results) == 32
|
||||
for result in results:
|
||||
if result.region == AWS_REGION_EU_WEST_1:
|
||||
assert result.status == "FAIL"
|
||||
@@ -153,7 +153,7 @@ class Test_guardduty_is_enabled:
|
||||
|
||||
check = guardduty_is_enabled()
|
||||
results = check.execute()
|
||||
assert len(results) == 29
|
||||
assert len(results) == 32
|
||||
for result in results:
|
||||
if result.region == AWS_REGION_EU_WEST_1:
|
||||
assert result.status == "FAIL"
|
||||
@@ -196,7 +196,7 @@ class Test_guardduty_is_enabled:
|
||||
|
||||
check = guardduty_is_enabled()
|
||||
results = check.execute()
|
||||
assert len(results) == 29
|
||||
assert len(results) == 32
|
||||
for result in results:
|
||||
if result.region == AWS_REGION_EU_WEST_1:
|
||||
assert result.status == "FAIL"
|
||||
|
||||
Reference in New Issue
Block a user