mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
feat(pip): Prepare for PyPI (#1531)
This commit is contained in:
191
tests/providers/aws/aws_provider_test.py
Normal file
191
tests/providers/aws/aws_provider_test.py
Normal file
@@ -0,0 +1,191 @@
|
||||
import json
|
||||
|
||||
import boto3
|
||||
import sure # noqa
|
||||
from moto import mock_iam, mock_organizations, mock_sts
|
||||
|
||||
from prowler.providers.aws.aws_provider import (
|
||||
assume_role,
|
||||
get_organizations_metadata,
|
||||
get_region_global_service,
|
||||
validate_credentials,
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Assume_Role, AWS_Audit_Info
|
||||
|
||||
ACCOUNT_ID = 123456789012
|
||||
|
||||
|
||||
class Test_AWS_Provider:
|
||||
@mock_sts
|
||||
@mock_iam
|
||||
def test_validate_credentials(self):
|
||||
# Create a mock IAM user
|
||||
iam_client = boto3.client("iam", region_name="us-east-1")
|
||||
iam_user = iam_client.create_user(UserName="test-user")["User"]
|
||||
# Create a mock IAM access keys
|
||||
access_key = iam_client.create_access_key(UserName=iam_user["UserName"])[
|
||||
"AccessKey"
|
||||
]
|
||||
access_key_id = access_key["AccessKeyId"]
|
||||
secret_access_key = access_key["SecretAccessKey"]
|
||||
# Create AWS session to validate
|
||||
session = boto3.session.Session(
|
||||
aws_access_key_id=access_key_id,
|
||||
aws_secret_access_key=secret_access_key,
|
||||
region_name="us-east-1",
|
||||
)
|
||||
# Validate AWS session
|
||||
get_caller_identity = validate_credentials(session)
|
||||
|
||||
get_caller_identity["Arn"].should.equal(iam_user["Arn"])
|
||||
get_caller_identity["UserId"].should.equal(iam_user["UserId"])
|
||||
# assert get_caller_identity["UserId"] == str(ACCOUNT_ID)
|
||||
|
||||
@mock_iam
|
||||
@mock_sts
|
||||
def test_assume_role(self):
|
||||
# Variables
|
||||
role_name = "test-role"
|
||||
role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/{role_name}"
|
||||
session_duration_seconds = 900
|
||||
audited_regions = "eu-west-1"
|
||||
sessionName = "ProwlerProAsessmentSession"
|
||||
# Boto 3 client to create our user
|
||||
iam_client = boto3.client("iam", region_name="us-east-1")
|
||||
# IAM user
|
||||
iam_user = iam_client.create_user(UserName="test-user")["User"]
|
||||
access_key = iam_client.create_access_key(UserName=iam_user["UserName"])[
|
||||
"AccessKey"
|
||||
]
|
||||
access_key_id = access_key["AccessKeyId"]
|
||||
secret_access_key = access_key["SecretAccessKey"]
|
||||
# New Boto3 session with the previously create user
|
||||
session = boto3.session.Session(
|
||||
aws_access_key_id=access_key_id,
|
||||
aws_secret_access_key=secret_access_key,
|
||||
region_name="us-east-1",
|
||||
)
|
||||
|
||||
# Fulfil the input session object for Prowler
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=session,
|
||||
audit_session=None,
|
||||
audited_account=None,
|
||||
audited_partition=None,
|
||||
audited_identity_arn=None,
|
||||
audited_user_id=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=AWS_Assume_Role(
|
||||
role_arn=role_arn,
|
||||
session_duration=session_duration_seconds,
|
||||
external_id=None,
|
||||
),
|
||||
audited_regions=audited_regions,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
|
||||
# Call assume_role
|
||||
assume_role_response = assume_role(audit_info)
|
||||
# Recover credentials for the assume role operation
|
||||
credentials = assume_role_response["Credentials"]
|
||||
# Test the response
|
||||
# SessionToken
|
||||
credentials["SessionToken"].should.have.length_of(356)
|
||||
credentials["SessionToken"].startswith("FQoGZXIvYXdzE")
|
||||
# AccessKeyId
|
||||
credentials["AccessKeyId"].should.have.length_of(20)
|
||||
credentials["AccessKeyId"].startswith("ASIA")
|
||||
# SecretAccessKey
|
||||
credentials["SecretAccessKey"].should.have.length_of(40)
|
||||
# Assumed Role
|
||||
assume_role_response["AssumedRoleUser"]["Arn"].should.equal(
|
||||
f"arn:aws:sts::{ACCOUNT_ID}:assumed-role/{role_name}/{sessionName}"
|
||||
)
|
||||
# AssumedRoleUser
|
||||
assert assume_role_response["AssumedRoleUser"]["AssumedRoleId"].startswith(
|
||||
"AROA"
|
||||
)
|
||||
assert assume_role_response["AssumedRoleUser"]["AssumedRoleId"].endswith(
|
||||
":" + sessionName
|
||||
)
|
||||
assume_role_response["AssumedRoleUser"]["AssumedRoleId"].should.have.length_of(
|
||||
21 + 1 + len(sessionName)
|
||||
)
|
||||
|
||||
@mock_organizations
|
||||
@mock_sts
|
||||
@mock_iam
|
||||
def test_organizations(self):
|
||||
client = boto3.client("organizations", region_name="us-east-1")
|
||||
iam_client = boto3.client("iam", region_name="us-east-1")
|
||||
sts_client = boto3.client("sts", region_name="us-east-1")
|
||||
|
||||
mockname = "mock-account"
|
||||
mockdomain = "moto-example.org"
|
||||
mockemail = "@".join([mockname, mockdomain])
|
||||
|
||||
org_id = client.create_organization(FeatureSet="ALL")["Organization"]["Id"]
|
||||
account_id = client.create_account(AccountName=mockname, Email=mockemail)[
|
||||
"CreateAccountStatus"
|
||||
]["AccountId"]
|
||||
|
||||
client.tag_resource(
|
||||
ResourceId=account_id, Tags=[{"Key": "key", "Value": "value"}]
|
||||
)
|
||||
|
||||
trust_policy_document = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": {
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::{account_id}:root".format(
|
||||
account_id=ACCOUNT_ID
|
||||
)
|
||||
},
|
||||
"Action": "sts:AssumeRole",
|
||||
},
|
||||
}
|
||||
iam_role_arn = iam_client.role_arn = iam_client.create_role(
|
||||
RoleName="test-role",
|
||||
AssumeRolePolicyDocument=json.dumps(trust_policy_document),
|
||||
)["Role"]["Arn"]
|
||||
session_name = "new-session"
|
||||
assumed_role = sts_client.assume_role(
|
||||
RoleArn=iam_role_arn, RoleSessionName=session_name
|
||||
)
|
||||
|
||||
org = get_organizations_metadata(account_id, assumed_role)
|
||||
|
||||
org.account_details_email.should.equal(mockemail)
|
||||
org.account_details_name.should.equal(mockname)
|
||||
org.account_details_arn.should.equal(
|
||||
"arn:aws:organizations::{0}:account/{1}/{2}".format(
|
||||
ACCOUNT_ID, org_id, account_id
|
||||
)
|
||||
)
|
||||
org.account_details_org.should.equal(org_id)
|
||||
org.account_details_tags.should.equal("key:value,")
|
||||
|
||||
def test_get_region_global_service(self):
|
||||
# Create mock audit_info
|
||||
input_audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=None,
|
||||
audited_account="123456789012",
|
||||
audited_identity_arn="test-arn",
|
||||
audited_user_id="test",
|
||||
audited_partition="aws",
|
||||
profile="default",
|
||||
profile_region="eu-west-1",
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=["eu-west-2", "eu-west-1"],
|
||||
organizations_metadata=None,
|
||||
)
|
||||
|
||||
assert (
|
||||
get_region_global_service(input_audit_info)
|
||||
== input_audit_info.audited_regions[0]
|
||||
)
|
||||
135
tests/providers/aws/lib/allowlist/allowlist_test.py
Normal file
135
tests/providers/aws/lib/allowlist/allowlist_test.py
Normal file
@@ -0,0 +1,135 @@
|
||||
import yaml
|
||||
from boto3 import resource, session
|
||||
from moto import mock_dynamodb, mock_s3
|
||||
|
||||
from prowler.providers.aws.lib.allowlist.allowlist import (
|
||||
is_allowlisted,
|
||||
parse_allowlist_file,
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_Allowlist:
|
||||
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test S3 allowlist
|
||||
@mock_s3
|
||||
def test_s3_allowlist(self):
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
# Create bucket and upload allowlist yaml
|
||||
s3_resource = resource("s3", region_name=AWS_REGION)
|
||||
s3_resource.create_bucket(Bucket="test-allowlist")
|
||||
s3_resource.Object("test-allowlist", "allowlist.yaml").put(
|
||||
Body=open(
|
||||
"tests/providers/aws/lib/allowlist/fixtures/allowlist.yaml",
|
||||
"rb",
|
||||
)
|
||||
)
|
||||
|
||||
with open("tests/providers/aws/lib/allowlist/fixtures/allowlist.yaml") as f:
|
||||
assert yaml.safe_load(f)["Allowlist"] == parse_allowlist_file(
|
||||
audit_info, "s3://test-allowlist/allowlist.yaml"
|
||||
)
|
||||
|
||||
# Test S3 allowlist
|
||||
@mock_dynamodb
|
||||
def test_dynamo_allowlist(self):
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
# Create table and put item
|
||||
dynamodb_resource = resource("dynamodb", region_name=AWS_REGION)
|
||||
table_name = "test-allowlist"
|
||||
params = {
|
||||
"TableName": table_name,
|
||||
"KeySchema": [
|
||||
{"AttributeName": "Accounts", "KeyType": "HASH"},
|
||||
{"AttributeName": "Checks", "KeyType": "RANGE"},
|
||||
],
|
||||
"AttributeDefinitions": [
|
||||
{"AttributeName": "Accounts", "AttributeType": "S"},
|
||||
{"AttributeName": "Checks", "AttributeType": "S"},
|
||||
],
|
||||
"ProvisionedThroughput": {
|
||||
"ReadCapacityUnits": 10,
|
||||
"WriteCapacityUnits": 10,
|
||||
},
|
||||
}
|
||||
table = dynamodb_resource.create_table(**params)
|
||||
table.put_item(
|
||||
Item={
|
||||
"Accounts": "*",
|
||||
"Checks": "iam_user_hardware_mfa_enabled",
|
||||
"Regions": ["eu-west-1", "us-east-1"],
|
||||
"Resources": ["keyword"],
|
||||
}
|
||||
)
|
||||
|
||||
assert (
|
||||
"keyword"
|
||||
in parse_allowlist_file(
|
||||
audit_info,
|
||||
"arn:aws:dynamodb:"
|
||||
+ AWS_REGION
|
||||
+ ":"
|
||||
+ str(AWS_ACCOUNT_NUMBER)
|
||||
+ ":table/"
|
||||
+ table_name,
|
||||
)["Accounts"]["*"]["Checks"]["iam_user_hardware_mfa_enabled"]["Resources"]
|
||||
)
|
||||
|
||||
# Allowlist checks
|
||||
def test_is_allowlisted(self):
|
||||
|
||||
# Allowlist example
|
||||
allowlist = {
|
||||
"Accounts": {
|
||||
"*": {
|
||||
"Checks": {
|
||||
"check_test": {
|
||||
"Regions": ["us-east-1", "eu-west-1"],
|
||||
"Resources": ["prowler", "^test"],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert is_allowlisted(
|
||||
allowlist, AWS_ACCOUNT_NUMBER, "check_test", AWS_REGION, "prowler"
|
||||
)
|
||||
|
||||
assert is_allowlisted(
|
||||
allowlist, AWS_ACCOUNT_NUMBER, "check_test", AWS_REGION, "prowler-test"
|
||||
)
|
||||
|
||||
assert is_allowlisted(
|
||||
allowlist, AWS_ACCOUNT_NUMBER, "check_test", AWS_REGION, "test-prowler"
|
||||
)
|
||||
|
||||
assert not (
|
||||
is_allowlisted(
|
||||
allowlist, AWS_ACCOUNT_NUMBER, "check_test", "us-east-2", "test"
|
||||
)
|
||||
)
|
||||
37
tests/providers/aws/lib/allowlist/fixtures/allowlist.yaml
Normal file
37
tests/providers/aws/lib/allowlist/fixtures/allowlist.yaml
Normal file
@@ -0,0 +1,37 @@
|
||||
### Account, Check and/or Region can be * to apply for all the cases
|
||||
### Resources is a list that can have either Regex or Keywords:
|
||||
########################### ALLOWLIST EXAMPLE ###########################
|
||||
Allowlist:
|
||||
Accounts:
|
||||
"123456789012":
|
||||
Checks:
|
||||
"iam_user_hardware_mfa_enabled":
|
||||
Regions:
|
||||
- "us-east-1"
|
||||
Resources:
|
||||
- "user-1" # Will ignore user-1 in check iam_user_hardware_mfa_enabled
|
||||
- "user-2" # Will ignore user-2 in check iam_user_hardware_mfa_enabled
|
||||
"*":
|
||||
Regions:
|
||||
- "*"
|
||||
Resources:
|
||||
- "test" # Will ignore every resource containing the string "test" in every account and region
|
||||
|
||||
"098765432109":
|
||||
Checks:
|
||||
"s3_bucket_object_versioning":
|
||||
Regions:
|
||||
- "eu-west-1"
|
||||
- "us-east-1"
|
||||
Resources:
|
||||
- "ci-logs" # Will ignore bucket "ci-logs" AND ALSO bucket "ci-logs-replica" in specified check and regions
|
||||
- "logs" # Will ignore EVERY BUCKET containing the string "logs" in specified check and regions
|
||||
- "[[:alnum:]]+-logs" # Will ignore all buckets containing the terms ci-logs, qa-logs, etc. in specified check and regions
|
||||
|
||||
# EXAMPLE: CONTROL TOWER (to migrate)
|
||||
# When using Control Tower, guardrails prevent access to certain protected resources. The allowlist
|
||||
# below ensures that warnings instead of errors are reported for the affected resources.
|
||||
#extra734:aws-controltower-logs-[[:digit:]]+-[[:alpha:]\-]+
|
||||
#extra734:aws-controltower-s3-access-logs-[[:digit:]]+-[[:alpha:]\-]+
|
||||
#extra764:aws-controltower-logs-[[:digit:]]+-[[:alpha:]\-]+
|
||||
#extra764:aws-controltower-s3-access-logs-[[:digit:]]+-[[:alpha:]\-]+
|
||||
33
tests/providers/aws/lib/arn/arn_test.py
Normal file
33
tests/providers/aws/lib/arn/arn_test.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import sure # noqa
|
||||
|
||||
from prowler.providers.aws.lib.arn.arn import arn_parsing
|
||||
|
||||
ACCOUNT_ID = "123456789012"
|
||||
RESOURCE_TYPE = "role"
|
||||
IAM_ROLE = "test-role"
|
||||
|
||||
|
||||
class Test_ARN_Parsing:
|
||||
def test_arn_parsing(self):
|
||||
test_cases = [
|
||||
{
|
||||
"input_arn": f"arn:aws:iam::{ACCOUNT_ID}:{RESOURCE_TYPE}/{IAM_ROLE}",
|
||||
"expected": {
|
||||
"partition": "aws",
|
||||
"service": "iam",
|
||||
"region": None,
|
||||
"account_id": ACCOUNT_ID,
|
||||
"resource_type": RESOURCE_TYPE,
|
||||
"resource": IAM_ROLE,
|
||||
},
|
||||
}
|
||||
]
|
||||
for test in test_cases:
|
||||
input_arn = test["input_arn"]
|
||||
parsed_arn = arn_parsing(input_arn)
|
||||
parsed_arn.partition.should.equal(test["expected"]["partition"])
|
||||
parsed_arn.service.should.equal(test["expected"]["service"])
|
||||
parsed_arn.region.should.equal(test["expected"]["region"])
|
||||
parsed_arn.account_id.should.equal(test["expected"]["account_id"])
|
||||
parsed_arn.resource_type.should.equal(test["expected"]["resource_type"])
|
||||
parsed_arn.resource.should.equal(test["expected"]["resource"])
|
||||
@@ -0,0 +1,169 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.accessanalyzer.accessanalyzer_service import (
|
||||
Analyzer,
|
||||
)
|
||||
|
||||
|
||||
class Test_accessanalyzer_enabled_without_findings:
|
||||
def test_no_analyzers(self):
|
||||
accessanalyzer_client = mock.MagicMock
|
||||
accessanalyzer_client.analyzers = []
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.accessanalyzer.accessanalyzer_service.AccessAnalyzer",
|
||||
new=accessanalyzer_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.accessanalyzer.accessanalyzer_enabled_without_findings.accessanalyzer_enabled_without_findings import (
|
||||
accessanalyzer_enabled_without_findings,
|
||||
)
|
||||
|
||||
check = accessanalyzer_enabled_without_findings()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_analyzer_not_available(self):
|
||||
# Include analyzers to check
|
||||
accessanalyzer_client = mock.MagicMock
|
||||
accessanalyzer_client.analyzers = [
|
||||
Analyzer(
|
||||
"",
|
||||
"Test Analyzer",
|
||||
"NOT_AVAILABLE",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"eu-west-1",
|
||||
)
|
||||
]
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.accessanalyzer.accessanalyzer_service.AccessAnalyzer",
|
||||
accessanalyzer_client,
|
||||
):
|
||||
from prowler.providers.aws.services.accessanalyzer.accessanalyzer_enabled_without_findings.accessanalyzer_enabled_without_findings import (
|
||||
accessanalyzer_enabled_without_findings,
|
||||
)
|
||||
|
||||
check = accessanalyzer_enabled_without_findings()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == "IAM Access Analyzer is not enabled"
|
||||
assert result[0].resource_id == "Test Analyzer"
|
||||
|
||||
def test_two_analyzers(self):
|
||||
accessanalyzer_client = mock.MagicMock
|
||||
accessanalyzer_client.analyzers = [
|
||||
Analyzer(
|
||||
"",
|
||||
"Test Analyzer",
|
||||
"NOT_AVAILABLE",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"eu-west-1",
|
||||
),
|
||||
Analyzer(
|
||||
"",
|
||||
"Test Analyzer",
|
||||
"ACTIVE",
|
||||
10,
|
||||
"",
|
||||
"",
|
||||
"eu-west-1",
|
||||
),
|
||||
]
|
||||
|
||||
# Patch AccessAnalyzer Client
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.accessanalyzer.accessanalyzer_service.AccessAnalyzer",
|
||||
new=accessanalyzer_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.accessanalyzer.accessanalyzer_enabled_without_findings.accessanalyzer_enabled_without_findings import (
|
||||
accessanalyzer_enabled_without_findings,
|
||||
)
|
||||
|
||||
check = accessanalyzer_enabled_without_findings()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 2
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == "IAM Access Analyzer is not enabled"
|
||||
assert result[0].resource_id == "Test Analyzer"
|
||||
assert result[1].status == "FAIL"
|
||||
assert (
|
||||
result[1].status_extended
|
||||
== "IAM Access Analyzer Test Analyzer has 10 active findings"
|
||||
)
|
||||
assert result[1].resource_id == "Test Analyzer"
|
||||
|
||||
def test_one_active_analyzer_without_findings(self):
|
||||
accessanalyzer_client = mock.MagicMock
|
||||
accessanalyzer_client.analyzers = [
|
||||
Analyzer(
|
||||
"",
|
||||
"Test Analyzer",
|
||||
"ACTIVE",
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
"eu-west-1",
|
||||
)
|
||||
]
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.accessanalyzer.accessanalyzer_service.AccessAnalyzer",
|
||||
new=accessanalyzer_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.accessanalyzer.accessanalyzer_enabled_without_findings.accessanalyzer_enabled_without_findings import (
|
||||
accessanalyzer_enabled_without_findings,
|
||||
)
|
||||
|
||||
check = accessanalyzer_enabled_without_findings()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "IAM Access Analyzer Test Analyzer has no active findings"
|
||||
)
|
||||
assert result[0].resource_id == "Test Analyzer"
|
||||
|
||||
def test_one_active_analyzer_not_active(self):
|
||||
accessanalyzer_client = mock.MagicMock
|
||||
accessanalyzer_client.analyzers = [
|
||||
Analyzer(
|
||||
"",
|
||||
"Test Analyzer",
|
||||
"FAILED",
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
"eu-west-1",
|
||||
)
|
||||
]
|
||||
# Patch AccessAnalyzer Client
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.accessanalyzer.accessanalyzer_service.AccessAnalyzer",
|
||||
new=accessanalyzer_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.accessanalyzer.accessanalyzer_enabled_without_findings.accessanalyzer_enabled_without_findings import (
|
||||
accessanalyzer_enabled_without_findings,
|
||||
)
|
||||
|
||||
check = accessanalyzer_enabled_without_findings()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "IAM Access Analyzer Test Analyzer is not active"
|
||||
)
|
||||
assert result[0].resource_id == "Test Analyzer"
|
||||
@@ -0,0 +1,95 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
import botocore
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.accessanalyzer.accessanalyzer_service import (
|
||||
AccessAnalyzer,
|
||||
)
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
# Mocking Access Analyzer Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
"""
|
||||
Mock every AWS API call using Boto3
|
||||
|
||||
As you can see the operation_name has the list_analyzers snake_case form but
|
||||
we are using the ListAnalyzers form.
|
||||
Rationale -> https://github.com/boto/botocore/blob/develop/botocore/client.py#L810:L816
|
||||
"""
|
||||
if operation_name == "ListAnalyzers":
|
||||
return {
|
||||
"analyzers": [
|
||||
{
|
||||
"arn": "ARN",
|
||||
"name": "Test Analyzer",
|
||||
"status": "Enabled",
|
||||
"findings": 0,
|
||||
"tags": "",
|
||||
"type": "ACCOUNT",
|
||||
"region": "eu-west-1",
|
||||
}
|
||||
]
|
||||
}
|
||||
if operation_name == "ListFindings":
|
||||
# If we only want to count the number of findings
|
||||
# we return a list of values just to count them
|
||||
return {"findings": [0, 1, 2]}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
# Mock generate_regional_clients()
|
||||
def mock_generate_regional_clients(service, audit_info):
|
||||
regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION)
|
||||
regional_client.region = AWS_REGION
|
||||
return {AWS_REGION: regional_client}
|
||||
|
||||
|
||||
# Patch every AWS call using Boto3 and generate_regional_clients to have 1 client
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
@patch(
|
||||
"prowler.providers.aws.services.accessanalyzer.accessanalyzer_service.generate_regional_clients",
|
||||
new=mock_generate_regional_clients,
|
||||
)
|
||||
class Test_AccessAnalyzer_Service:
|
||||
# Test AccessAnalyzer Client
|
||||
def test__get_client__(self):
|
||||
access_analyzer = AccessAnalyzer(current_audit_info)
|
||||
assert (
|
||||
access_analyzer.regional_clients[AWS_REGION].__class__.__name__
|
||||
== "AccessAnalyzer"
|
||||
)
|
||||
|
||||
# Test AccessAnalyzer Session
|
||||
def test__get_session__(self):
|
||||
access_analyzer = AccessAnalyzer(current_audit_info)
|
||||
assert access_analyzer.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test AccessAnalyzer Service
|
||||
def test__get_service__(self):
|
||||
access_analyzer = AccessAnalyzer(current_audit_info)
|
||||
assert access_analyzer.service == "accessanalyzer"
|
||||
|
||||
def test__list_analyzers__(self):
|
||||
# Set partition for the service
|
||||
current_audit_info.audited_partition = "aws"
|
||||
access_analyzer = AccessAnalyzer(current_audit_info)
|
||||
assert len(access_analyzer.analyzers) == 1
|
||||
assert access_analyzer.analyzers[0].arn == "ARN"
|
||||
assert access_analyzer.analyzers[0].name == "Test Analyzer"
|
||||
assert access_analyzer.analyzers[0].status == "Enabled"
|
||||
assert access_analyzer.analyzers[0].tags == ""
|
||||
assert access_analyzer.analyzers[0].type == "ACCOUNT"
|
||||
assert access_analyzer.analyzers[0].region == AWS_REGION
|
||||
|
||||
def test__list_findings__(self):
|
||||
# Set partition for the service
|
||||
current_audit_info.audited_partition = "aws"
|
||||
access_analyzer = AccessAnalyzer(current_audit_info)
|
||||
assert len(access_analyzer.analyzers) == 1
|
||||
assert access_analyzer.analyzers[0].findings_count == 3
|
||||
@@ -0,0 +1,69 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_acm
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_acm_certificates_expiration_check:
|
||||
@mock_acm
|
||||
def test_acm_certificate_expirated(self):
|
||||
# Generate ACM Client
|
||||
acm_client = client("acm", region_name=AWS_REGION)
|
||||
# Request ACM certificate
|
||||
certificate = acm_client.request_certificate(
|
||||
DomainName="test.com",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.acm.acm_service import ACM
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.acm.acm_certificates_expiration_check.acm_certificates_expiration_check.acm_client",
|
||||
new=ACM(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.acm.acm_certificates_expiration_check.acm_certificates_expiration_check import (
|
||||
acm_certificates_expiration_check,
|
||||
)
|
||||
|
||||
service_client.certificates[0].expiration_days = 5
|
||||
check = acm_certificates_expiration_check()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_id == "test.com"
|
||||
assert result[0].resource_arn == certificate["CertificateArn"]
|
||||
|
||||
@mock_acm
|
||||
def test_acm_certificate_not_expirated(self):
|
||||
# Generate ACM Client
|
||||
acm_client = client("acm", region_name=AWS_REGION)
|
||||
# Request ACM certificate
|
||||
certificate = acm_client.request_certificate(
|
||||
DomainName="test.com",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.acm.acm_service import ACM
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.acm.acm_certificates_expiration_check.acm_certificates_expiration_check.acm_client",
|
||||
new=ACM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.acm.acm_certificates_expiration_check.acm_certificates_expiration_check import (
|
||||
acm_certificates_expiration_check,
|
||||
)
|
||||
|
||||
check = acm_certificates_expiration_check()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == "test.com"
|
||||
assert result[0].resource_arn == certificate["CertificateArn"]
|
||||
@@ -0,0 +1,113 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_acm
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_acm_certificates_transparency_logs_enabled:
|
||||
@mock_acm
|
||||
def test_acm_certificate_with_logging(self):
|
||||
# Generate ACM Client
|
||||
acm_client = client("acm", region_name=AWS_REGION)
|
||||
# Request ACM certificate
|
||||
certificate = acm_client.request_certificate(
|
||||
DomainName="test.com",
|
||||
Options={"CertificateTransparencyLoggingPreference": "ENABLED"},
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.acm.acm_service import ACM
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.acm.acm_certificates_transparency_logs_enabled.acm_certificates_transparency_logs_enabled.acm_client",
|
||||
new=ACM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.acm.acm_certificates_transparency_logs_enabled.acm_certificates_transparency_logs_enabled import (
|
||||
acm_certificates_transparency_logs_enabled,
|
||||
)
|
||||
|
||||
check = acm_certificates_transparency_logs_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "ACM Certificate for test.com has Certificate Transparency logging enabled."
|
||||
)
|
||||
assert result[0].resource_id == "test.com"
|
||||
assert result[0].resource_arn == certificate["CertificateArn"]
|
||||
|
||||
@mock_acm
|
||||
def test_acm_certificate_without_logging(self):
|
||||
# Generate ACM Client
|
||||
acm_client = client("acm", region_name=AWS_REGION)
|
||||
# Request ACM certificate
|
||||
certificate = acm_client.request_certificate(
|
||||
DomainName="test.com",
|
||||
Options={"CertificateTransparencyLoggingPreference": "ENABLED"},
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.acm.acm_service import ACM
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.acm.acm_certificates_transparency_logs_enabled.acm_certificates_transparency_logs_enabled.acm_client",
|
||||
new=ACM(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.acm.acm_certificates_transparency_logs_enabled.acm_certificates_transparency_logs_enabled import (
|
||||
acm_certificates_transparency_logs_enabled,
|
||||
)
|
||||
|
||||
service_client.certificates[0].transparency_logging = False
|
||||
check = acm_certificates_transparency_logs_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "ACM Certificate for test.com has Certificate Transparency logging disabled."
|
||||
)
|
||||
assert result[0].resource_id == "test.com"
|
||||
assert result[0].resource_arn == certificate["CertificateArn"]
|
||||
|
||||
@mock_acm
|
||||
def test_acm_default_certificate(self):
|
||||
# Generate ACM Client
|
||||
acm_client = client("acm", region_name=AWS_REGION)
|
||||
# Request ACM certificate
|
||||
certificate = acm_client.request_certificate(
|
||||
DomainName="test.com",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.acm.acm_service import ACM
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.acm.acm_certificates_transparency_logs_enabled.acm_certificates_transparency_logs_enabled.acm_client",
|
||||
new=ACM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.acm.acm_certificates_transparency_logs_enabled.acm_certificates_transparency_logs_enabled import (
|
||||
acm_certificates_transparency_logs_enabled,
|
||||
)
|
||||
|
||||
check = acm_certificates_transparency_logs_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "ACM Certificate for test.com has Certificate Transparency logging enabled."
|
||||
)
|
||||
assert result[0].resource_id == "test.com"
|
||||
assert result[0].resource_arn == certificate["CertificateArn"]
|
||||
94
tests/providers/aws/services/acm/acm_service_test.py
Normal file
94
tests/providers/aws/services/acm/acm_service_test.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from boto3 import client, session
|
||||
from moto import mock_acm
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.acm.acm_service import ACM
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_ACM_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test ACM Service
|
||||
@mock_acm
|
||||
def test_service(self):
|
||||
# ACM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
acm = ACM(audit_info)
|
||||
assert acm.service == "acm"
|
||||
|
||||
# Test ACM Client
|
||||
@mock_acm
|
||||
def test_client(self):
|
||||
# ACM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
acm = ACM(audit_info)
|
||||
for regional_client in acm.regional_clients.values():
|
||||
assert regional_client.__class__.__name__ == "ACM"
|
||||
|
||||
# Test ACM Session
|
||||
@mock_acm
|
||||
def test__get_session__(self):
|
||||
# ACM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
acm = ACM(audit_info)
|
||||
assert acm.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test ACM Session
|
||||
@mock_acm
|
||||
def test_audited_account(self):
|
||||
# ACM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
acm = ACM(audit_info)
|
||||
assert acm.audited_account == AWS_ACCOUNT_NUMBER
|
||||
|
||||
# Test ACM List Certificates
|
||||
@mock_acm
|
||||
def test__list_certificates__(self):
|
||||
# Generate ACM Client
|
||||
acm_client = client("acm", region_name=AWS_REGION)
|
||||
# Request ACM certificate
|
||||
certificate = acm_client.request_certificate(
|
||||
DomainName="test.com",
|
||||
)
|
||||
# ACM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
acm = ACM(audit_info)
|
||||
assert len(acm.certificates) == 1
|
||||
assert acm.certificates[0].arn == certificate["CertificateArn"]
|
||||
|
||||
# Test ACM Describe Certificates
|
||||
@mock_acm
|
||||
def test__describe_certificates__(self):
|
||||
# Generate ACM Client
|
||||
acm_client = client("acm", region_name=AWS_REGION)
|
||||
# Request ACM certificate
|
||||
certificate = acm_client.request_certificate(
|
||||
DomainName="test.com",
|
||||
)
|
||||
# ACM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
acm = ACM(audit_info)
|
||||
assert acm.certificates[0].type == "AMAZON_ISSUED"
|
||||
assert acm.certificates[0].arn == certificate["CertificateArn"]
|
||||
@@ -0,0 +1,125 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_apigateway, mock_iam, mock_lambda
|
||||
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_apigateway_authorizers_enabled:
|
||||
@mock_apigateway
|
||||
def test_apigateway_no_rest_apis(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_authorizers_enabled.apigateway_authorizers_enabled.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_authorizers_enabled.apigateway_authorizers_enabled import (
|
||||
apigateway_authorizers_enabled,
|
||||
)
|
||||
|
||||
check = apigateway_authorizers_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_apigateway
|
||||
@mock_iam
|
||||
@mock_lambda
|
||||
def test_apigateway_one_rest_api_with_lambda_authorizer(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
lambda_client = client("lambda", region_name=AWS_REGION)
|
||||
iam_client = client("iam")
|
||||
# Create APIGateway Rest API
|
||||
role_arn = iam_client.create_role(
|
||||
RoleName="my-role",
|
||||
AssumeRolePolicyDocument="some policy",
|
||||
)["Role"]["Arn"]
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
authorizer = lambda_client.create_function(
|
||||
FunctionName="lambda-authorizer",
|
||||
Runtime="python3.7",
|
||||
Role=role_arn,
|
||||
Handler="lambda_function.lambda_handler",
|
||||
Code={
|
||||
"ImageUri": "123456789012.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest"
|
||||
},
|
||||
)
|
||||
apigateway_client.create_authorizer(
|
||||
name="test",
|
||||
restApiId=rest_api["id"],
|
||||
type="TOKEN",
|
||||
authorizerUri=f"arn:aws:apigateway:{apigateway_client.meta.region_name}:lambda:path/2015-03-31/functions/arn:aws:lambda:{apigateway_client.meta.region_name}:{ACCOUNT_ID}:function:{authorizer['FunctionName']}/invocations",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_authorizers_enabled.apigateway_authorizers_enabled.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_authorizers_enabled.apigateway_authorizers_enabled import (
|
||||
apigateway_authorizers_enabled,
|
||||
)
|
||||
|
||||
check = apigateway_authorizers_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "PASS"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} has authorizer configured."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
|
||||
@mock_apigateway
|
||||
def test_apigateway_one_rest_api_without_lambda_authorizer(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Rest API
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_authorizers_enabled.apigateway_authorizers_enabled.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_authorizers_enabled.apigateway_authorizers_enabled import (
|
||||
apigateway_authorizers_enabled,
|
||||
)
|
||||
|
||||
check = apigateway_authorizers_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "FAIL"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} has not authorizer configured."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
@@ -0,0 +1,146 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_apigateway
|
||||
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import Stage
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_apigateway_client_certificate_enabled:
|
||||
@mock_apigateway
|
||||
def test_apigateway_no_stages(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Rest API
|
||||
apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_client_certificate_enabled.apigateway_client_certificate_enabled.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_client_certificate_enabled.apigateway_client_certificate_enabled import (
|
||||
apigateway_client_certificate_enabled,
|
||||
)
|
||||
|
||||
check = apigateway_client_certificate_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_apigateway
|
||||
def test_apigateway_one_stage_without_certificate(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Deployment Stage
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
# Get the rest api's root id
|
||||
root_resource_id = apigateway_client.get_resources(restApiId=rest_api["id"])[
|
||||
"items"
|
||||
][0]["id"]
|
||||
resource = apigateway_client.create_resource(
|
||||
restApiId=rest_api["id"],
|
||||
parentId=root_resource_id,
|
||||
pathPart="test-path",
|
||||
)
|
||||
apigateway_client.put_method(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
authorizationType="NONE",
|
||||
)
|
||||
apigateway_client.put_integration(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
type="HTTP",
|
||||
integrationHttpMethod="POST",
|
||||
uri="http://test.com",
|
||||
)
|
||||
apigateway_client.create_deployment(
|
||||
restApiId=rest_api["id"],
|
||||
stageName="test",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_client_certificate_enabled.apigateway_client_certificate_enabled.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_client_certificate_enabled.apigateway_client_certificate_enabled import (
|
||||
apigateway_client_certificate_enabled,
|
||||
)
|
||||
|
||||
check = apigateway_client_certificate_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} in stage test has not client certificate enabled."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
|
||||
@mock_apigateway
|
||||
def test_apigateway_one_stage_with_certificate(self):
|
||||
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Deployment Stage
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_client_certificate_enabled.apigateway_client_certificate_enabled.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_client_certificate_enabled.apigateway_client_certificate_enabled import (
|
||||
apigateway_client_certificate_enabled,
|
||||
)
|
||||
|
||||
service_client.rest_apis[0].stages.append(
|
||||
Stage(
|
||||
"test",
|
||||
logging=True,
|
||||
client_certificate=True,
|
||||
waf=True,
|
||||
)
|
||||
)
|
||||
|
||||
check = apigateway_client_certificate_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} in stage test has client certificate enabled."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
@@ -0,0 +1,111 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_apigateway
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_apigateway_endpoint_public:
|
||||
@mock_apigateway
|
||||
def test_apigateway_no_rest_apis(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_endpoint_public.apigateway_endpoint_public.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_endpoint_public.apigateway_endpoint_public import (
|
||||
apigateway_endpoint_public,
|
||||
)
|
||||
|
||||
check = apigateway_endpoint_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_apigateway
|
||||
def test_apigateway_one_private_rest_api(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Deployment Stage
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
endpointConfiguration={
|
||||
"types": [
|
||||
"PRIVATE",
|
||||
]
|
||||
},
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_endpoint_public.apigateway_endpoint_public.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_endpoint_public.apigateway_endpoint_public import (
|
||||
apigateway_endpoint_public,
|
||||
)
|
||||
|
||||
check = apigateway_endpoint_public()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "PASS"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} is private."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
|
||||
@mock_apigateway
|
||||
def test_apigateway_one_public_rest_api(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Deployment Stage
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
endpointConfiguration={
|
||||
"types": [
|
||||
"EDGE",
|
||||
]
|
||||
},
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_endpoint_public.apigateway_endpoint_public.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_endpoint_public.apigateway_endpoint_public import (
|
||||
apigateway_endpoint_public,
|
||||
)
|
||||
|
||||
check = apigateway_endpoint_public()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "FAIL"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} is internet accesible."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
@@ -0,0 +1,166 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_apigateway
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_apigateway_logging_enabled:
|
||||
@mock_apigateway
|
||||
def test_apigateway_no_rest_apis(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_logging_enabled.apigateway_logging_enabled.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_logging_enabled.apigateway_logging_enabled import (
|
||||
apigateway_logging_enabled,
|
||||
)
|
||||
|
||||
check = apigateway_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_apigateway
|
||||
def test_apigateway_one_rest_api_with_logging(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
# Get the rest api's root id
|
||||
root_resource_id = apigateway_client.get_resources(restApiId=rest_api["id"])[
|
||||
"items"
|
||||
][0]["id"]
|
||||
resource = apigateway_client.create_resource(
|
||||
restApiId=rest_api["id"],
|
||||
parentId=root_resource_id,
|
||||
pathPart="test-path",
|
||||
)
|
||||
apigateway_client.put_method(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
authorizationType="NONE",
|
||||
)
|
||||
apigateway_client.put_integration(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
type="HTTP",
|
||||
integrationHttpMethod="POST",
|
||||
uri="http://test.com",
|
||||
)
|
||||
apigateway_client.create_deployment(
|
||||
restApiId=rest_api["id"],
|
||||
stageName="test",
|
||||
)
|
||||
apigateway_client.update_stage(
|
||||
restApiId=rest_api["id"],
|
||||
stageName="test",
|
||||
patchOperations=[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/*/*/logging/loglevel",
|
||||
"value": "INFO",
|
||||
},
|
||||
],
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_logging_enabled.apigateway_logging_enabled.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_logging_enabled.apigateway_logging_enabled import (
|
||||
apigateway_logging_enabled,
|
||||
)
|
||||
|
||||
check = apigateway_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "PASS"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} in stage test has logging enabled."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
|
||||
@mock_apigateway
|
||||
def test_apigateway_one_rest_api_without_logging(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Rest API
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
# Get the rest api's root id
|
||||
root_resource_id = apigateway_client.get_resources(restApiId=rest_api["id"])[
|
||||
"items"
|
||||
][0]["id"]
|
||||
resource = apigateway_client.create_resource(
|
||||
restApiId=rest_api["id"],
|
||||
parentId=root_resource_id,
|
||||
pathPart="test-path",
|
||||
)
|
||||
apigateway_client.put_method(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
authorizationType="NONE",
|
||||
)
|
||||
apigateway_client.put_integration(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
type="HTTP",
|
||||
integrationHttpMethod="POST",
|
||||
uri="http://test.com",
|
||||
)
|
||||
apigateway_client.create_deployment(
|
||||
restApiId=rest_api["id"],
|
||||
stageName="test",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_logging_enabled.apigateway_logging_enabled.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_logging_enabled.apigateway_logging_enabled import (
|
||||
apigateway_logging_enabled,
|
||||
)
|
||||
|
||||
check = apigateway_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "FAIL"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} in stage test has logging disabled."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
@@ -0,0 +1,165 @@
|
||||
from boto3 import client, session
|
||||
from moto import mock_apigateway
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import APIGateway
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_APIGateway_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test APIGateway Service
|
||||
@mock_apigateway
|
||||
def test_service(self):
|
||||
# APIGateway client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigateway = APIGateway(audit_info)
|
||||
assert apigateway.service == "apigateway"
|
||||
|
||||
# Test APIGateway Client
|
||||
@mock_apigateway
|
||||
def test_client(self):
|
||||
# APIGateway client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigateway = APIGateway(audit_info)
|
||||
for regional_client in apigateway.regional_clients.values():
|
||||
assert regional_client.__class__.__name__ == "APIGateway"
|
||||
|
||||
# Test APIGateway Session
|
||||
@mock_apigateway
|
||||
def test__get_session__(self):
|
||||
# APIGateway client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigateway = APIGateway(audit_info)
|
||||
assert apigateway.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test APIGateway Session
|
||||
@mock_apigateway
|
||||
def test_audited_account(self):
|
||||
# APIGateway client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigateway = APIGateway(audit_info)
|
||||
assert apigateway.audited_account == AWS_ACCOUNT_NUMBER
|
||||
|
||||
# Test APIGateway Get Rest APIs
|
||||
@mock_apigateway
|
||||
def test__get_rest_apis__(self):
|
||||
# Generate APIGateway Client
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Rest API
|
||||
apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
# APIGateway client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigateway = APIGateway(audit_info)
|
||||
assert len(apigateway.rest_apis) == len(
|
||||
apigateway_client.get_rest_apis()["items"]
|
||||
)
|
||||
|
||||
# Test APIGateway Get Authorizers
|
||||
@mock_apigateway
|
||||
def test__get_authorizers__(self):
|
||||
# Generate APIGateway Client
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Rest API
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
# Create authorizer
|
||||
apigateway_client.create_authorizer(
|
||||
name="test-authorizer",
|
||||
restApiId=rest_api["id"],
|
||||
type="TOKEN",
|
||||
)
|
||||
# APIGateway client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigateway = APIGateway(audit_info)
|
||||
assert apigateway.rest_apis[0].authorizer is True
|
||||
|
||||
# Test APIGateway Get Rest API
|
||||
@mock_apigateway
|
||||
def test__get_rest_api__(self):
|
||||
# Generate APIGateway Client
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create private APIGateway Rest API
|
||||
apigateway_client.create_rest_api(
|
||||
name="test-rest-api", endpointConfiguration={"types": ["PRIVATE"]}
|
||||
)
|
||||
# APIGateway client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigateway = APIGateway(audit_info)
|
||||
assert apigateway.rest_apis[0].public_endpoint is False
|
||||
|
||||
# Test APIGateway Get Stages
|
||||
@mock_apigateway
|
||||
def test__get_stages__(self):
|
||||
# Generate APIGateway Client
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Rest API and a deployment stage
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
# Get the rest api's root id
|
||||
root_resource_id = apigateway_client.get_resources(restApiId=rest_api["id"])[
|
||||
"items"
|
||||
][0]["id"]
|
||||
resource = apigateway_client.create_resource(
|
||||
restApiId=rest_api["id"],
|
||||
parentId=root_resource_id,
|
||||
pathPart="test-path",
|
||||
)
|
||||
apigateway_client.put_method(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
authorizationType="NONE",
|
||||
)
|
||||
apigateway_client.put_integration(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
type="HTTP",
|
||||
integrationHttpMethod="POST",
|
||||
uri="http://test.com",
|
||||
)
|
||||
apigateway_client.create_deployment(
|
||||
restApiId=rest_api["id"],
|
||||
stageName="test",
|
||||
)
|
||||
apigateway_client.update_stage(
|
||||
restApiId=rest_api["id"],
|
||||
stageName="test",
|
||||
patchOperations=[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/*/*/logging/loglevel",
|
||||
"value": "INFO",
|
||||
},
|
||||
],
|
||||
)
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigateway = APIGateway(audit_info)
|
||||
assert apigateway.rest_apis[0].stages[0].logging is True
|
||||
@@ -0,0 +1,172 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_apigateway, mock_wafv2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_apigateway_waf_acl_attached:
|
||||
@mock_apigateway
|
||||
def test_apigateway_no_rest_apis(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_waf_acl_attached.apigateway_waf_acl_attached.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_waf_acl_attached.apigateway_waf_acl_attached import (
|
||||
apigateway_waf_acl_attached,
|
||||
)
|
||||
|
||||
check = apigateway_waf_acl_attached()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_apigateway
|
||||
@mock_wafv2
|
||||
def test_apigateway_one_rest_api_with_waf(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
waf_client = client("wafv2", region_name=AWS_REGION)
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
# Get the rest api's root id
|
||||
root_resource_id = apigateway_client.get_resources(restApiId=rest_api["id"])[
|
||||
"items"
|
||||
][0]["id"]
|
||||
resource = apigateway_client.create_resource(
|
||||
restApiId=rest_api["id"],
|
||||
parentId=root_resource_id,
|
||||
pathPart="test-path",
|
||||
)
|
||||
apigateway_client.put_method(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
authorizationType="NONE",
|
||||
)
|
||||
apigateway_client.put_integration(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
type="HTTP",
|
||||
integrationHttpMethod="POST",
|
||||
uri="http://test.com",
|
||||
)
|
||||
apigateway_client.create_deployment(
|
||||
restApiId=rest_api["id"],
|
||||
stageName="test",
|
||||
)
|
||||
waf_arn = waf_client.create_web_acl(
|
||||
Name="test",
|
||||
Scope="REGIONAL",
|
||||
DefaultAction={"Allow": {}},
|
||||
VisibilityConfig={
|
||||
"SampledRequestsEnabled": False,
|
||||
"CloudWatchMetricsEnabled": False,
|
||||
"MetricName": "idk",
|
||||
},
|
||||
)["Summary"]["ARN"]
|
||||
waf_client.associate_web_acl(
|
||||
WebACLArn=waf_arn,
|
||||
ResourceArn=f"arn:aws:apigateway:{apigateway_client.meta.region_name}::/restapis/{rest_api['id']}/stages/test",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_waf_acl_attached.apigateway_waf_acl_attached.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_waf_acl_attached.apigateway_waf_acl_attached import (
|
||||
apigateway_waf_acl_attached,
|
||||
)
|
||||
|
||||
check = apigateway_waf_acl_attached()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "PASS"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} in stage test has {waf_arn} WAF ACL attached."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
|
||||
@mock_apigateway
|
||||
def test_apigateway_one_rest_api_without_waf(self):
|
||||
# Create APIGateway Mocked Resources
|
||||
apigateway_client = client("apigateway", region_name=AWS_REGION)
|
||||
# Create APIGateway Rest API
|
||||
rest_api = apigateway_client.create_rest_api(
|
||||
name="test-rest-api",
|
||||
)
|
||||
# Get the rest api's root id
|
||||
root_resource_id = apigateway_client.get_resources(restApiId=rest_api["id"])[
|
||||
"items"
|
||||
][0]["id"]
|
||||
resource = apigateway_client.create_resource(
|
||||
restApiId=rest_api["id"],
|
||||
parentId=root_resource_id,
|
||||
pathPart="test-path",
|
||||
)
|
||||
apigateway_client.put_method(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
authorizationType="NONE",
|
||||
)
|
||||
apigateway_client.put_integration(
|
||||
restApiId=rest_api["id"],
|
||||
resourceId=resource["id"],
|
||||
httpMethod="GET",
|
||||
type="HTTP",
|
||||
integrationHttpMethod="POST",
|
||||
uri="http://test.com",
|
||||
)
|
||||
apigateway_client.create_deployment(
|
||||
restApiId=rest_api["id"],
|
||||
stageName="test",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigateway.apigateway_service import (
|
||||
APIGateway,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigateway.apigateway_waf_acl_attached.apigateway_waf_acl_attached.apigateway_client",
|
||||
new=APIGateway(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigateway.apigateway_waf_acl_attached.apigateway_waf_acl_attached import (
|
||||
apigateway_waf_acl_attached,
|
||||
)
|
||||
|
||||
check = apigateway_waf_acl_attached()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "FAIL"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway test-rest-api ID {rest_api['id']} in stage test has not WAF ACL attached."
|
||||
)
|
||||
assert result[0].resource_id == "test-rest-api"
|
||||
@@ -0,0 +1,94 @@
|
||||
from unittest import mock
|
||||
|
||||
import botocore
|
||||
from boto3 import client
|
||||
from mock import patch
|
||||
from moto import mock_apigatewayv2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
# Mocking ApiGatewayV2 Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
"""
|
||||
We have to mock every AWS API call using Boto3
|
||||
|
||||
Rationale -> https://github.com/boto/botocore/blob/develop/botocore/client.py#L810:L816
|
||||
"""
|
||||
if operation_name == "GetAuthorizers":
|
||||
return {"Items": [{"AuthorizerId": "authorizer-id", "Name": "test-authorizer"}]}
|
||||
elif operation_name == "GetStages":
|
||||
return {
|
||||
"Items": [
|
||||
{
|
||||
"AccessLogSettings": {
|
||||
"DestinationArn": "string",
|
||||
"Format": "string",
|
||||
},
|
||||
"StageName": "test-stage",
|
||||
}
|
||||
]
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
class Test_apigatewayv2_access_logging_enabled:
|
||||
@mock_apigatewayv2
|
||||
def test_apigateway_no_apis(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_service import (
|
||||
ApiGatewayV2,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigatewayv2.apigatewayv2_access_logging_enabled.apigatewayv2_access_logging_enabled.apigatewayv2_client",
|
||||
new=ApiGatewayV2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_access_logging_enabled.apigatewayv2_access_logging_enabled import (
|
||||
apigatewayv2_access_logging_enabled,
|
||||
)
|
||||
|
||||
check = apigatewayv2_access_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_apigatewayv2
|
||||
def test_apigateway_one_api_with_logging_in_stage(self):
|
||||
# Create ApiGatewayV2 Mocked Resources
|
||||
apigatewayv2_client = client("apigatewayv2", region_name=AWS_REGION)
|
||||
# Create ApiGatewayV2 API
|
||||
api = apigatewayv2_client.create_api(Name="test-api", ProtocolType="HTTP")
|
||||
# Get stages mock with stage with logging
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_service import (
|
||||
ApiGatewayV2,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigatewayv2.apigatewayv2_access_logging_enabled.apigatewayv2_access_logging_enabled.apigatewayv2_client",
|
||||
new=ApiGatewayV2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_access_logging_enabled.apigatewayv2_access_logging_enabled import (
|
||||
apigatewayv2_access_logging_enabled,
|
||||
)
|
||||
|
||||
check = apigatewayv2_access_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "PASS"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway V2 test-api ID {api['ApiId']} in stage test-stage has access logging enabled."
|
||||
)
|
||||
assert result[0].resource_id == "test-api"
|
||||
@@ -0,0 +1,100 @@
|
||||
from unittest import mock
|
||||
|
||||
import botocore
|
||||
from boto3 import client
|
||||
from mock import patch
|
||||
from moto import mock_apigatewayv2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
# Mocking ApiGatewayV2 Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
"""
|
||||
We have to mock every AWS API call using Boto3
|
||||
|
||||
Rationale -> https://github.com/boto/botocore/blob/develop/botocore/client.py#L810:L816
|
||||
"""
|
||||
if operation_name == "GetAuthorizers":
|
||||
return {"Items": [{"AuthorizerId": "authorizer-id", "Name": "test-authorizer"}]}
|
||||
elif operation_name == "GetStages":
|
||||
return {
|
||||
"Items": [
|
||||
{
|
||||
"AccessLogSettings": {
|
||||
"DestinationArn": "string",
|
||||
"Format": "string",
|
||||
},
|
||||
"StageName": "test-stage",
|
||||
}
|
||||
]
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
class Test_apigatewayv2_authorizers_enabled:
|
||||
@mock_apigatewayv2
|
||||
def test_apigateway_no_apis(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_service import (
|
||||
ApiGatewayV2,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigatewayv2.apigatewayv2_authorizers_enabled.apigatewayv2_authorizers_enabled.apigatewayv2_client",
|
||||
new=ApiGatewayV2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_authorizers_enabled.apigatewayv2_authorizers_enabled import (
|
||||
apigatewayv2_authorizers_enabled,
|
||||
)
|
||||
|
||||
check = apigatewayv2_authorizers_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_apigatewayv2
|
||||
def test_apigateway_one_api_with_authorizer(self):
|
||||
# Create ApiGatewayV2 Mocked Resources
|
||||
apigatewayv2_client = client("apigatewayv2", region_name=AWS_REGION)
|
||||
# Create ApiGatewayV2 API
|
||||
api = apigatewayv2_client.create_api(Name="test-api", ProtocolType="HTTP")
|
||||
apigatewayv2_client.create_authorizer(
|
||||
ApiId=api["ApiId"],
|
||||
AuthorizerType="REQUEST",
|
||||
IdentitySource=[],
|
||||
Name="auth1",
|
||||
AuthorizerPayloadFormatVersion="2.0",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_service import (
|
||||
ApiGatewayV2,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.apigatewayv2.apigatewayv2_authorizers_enabled.apigatewayv2_authorizers_enabled.apigatewayv2_client",
|
||||
new=ApiGatewayV2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_authorizers_enabled.apigatewayv2_authorizers_enabled import (
|
||||
apigatewayv2_authorizers_enabled,
|
||||
)
|
||||
|
||||
check = apigatewayv2_authorizers_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert result[0].status == "PASS"
|
||||
assert len(result) == 1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"API Gateway V2 test-api ID {api['ApiId']} has authorizer configured."
|
||||
)
|
||||
assert result[0].resource_id == "test-api"
|
||||
@@ -0,0 +1,139 @@
|
||||
import botocore
|
||||
from boto3 import client, session
|
||||
from mock import patch
|
||||
from moto import mock_apigatewayv2
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_service import (
|
||||
ApiGatewayV2,
|
||||
)
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
# Mocking ApiGatewayV2 Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
"""
|
||||
We have to mock every AWS API call using Boto3
|
||||
|
||||
Rationale -> https://github.com/boto/botocore/blob/develop/botocore/client.py#L810:L816
|
||||
"""
|
||||
if operation_name == "GetAuthorizers":
|
||||
return {"Items": [{"AuthorizerId": "authorizer-id", "Name": "test-authorizer"}]}
|
||||
elif operation_name == "GetStages":
|
||||
return {
|
||||
"Items": [
|
||||
{
|
||||
"AccessLogSettings": {
|
||||
"DestinationArn": "string",
|
||||
"Format": "string",
|
||||
},
|
||||
"StageName": "test-stage",
|
||||
}
|
||||
]
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
class Test_ApiGatewayV2_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test ApiGatewayV2 Service
|
||||
@mock_apigatewayv2
|
||||
def test_service(self):
|
||||
# ApiGatewayV2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigatewayv2 = ApiGatewayV2(audit_info)
|
||||
assert apigatewayv2.service == "apigatewayv2"
|
||||
|
||||
# Test ApiGatewayV2 Client
|
||||
@mock_apigatewayv2
|
||||
def test_client(self):
|
||||
# ApiGatewayV2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigatewayv2 = ApiGatewayV2(audit_info)
|
||||
for regional_client in apigatewayv2.regional_clients.values():
|
||||
assert regional_client.__class__.__name__ == "ApiGatewayV2"
|
||||
|
||||
# Test ApiGatewayV2 Session
|
||||
@mock_apigatewayv2
|
||||
def test__get_session__(self):
|
||||
# ApiGatewayV2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigatewayv2 = ApiGatewayV2(audit_info)
|
||||
assert apigatewayv2.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test ApiGatewayV2 Session
|
||||
@mock_apigatewayv2
|
||||
def test_audited_account(self):
|
||||
# ApiGatewayV2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigatewayv2 = ApiGatewayV2(audit_info)
|
||||
assert apigatewayv2.audited_account == AWS_ACCOUNT_NUMBER
|
||||
|
||||
# Test ApiGatewayV2 Get APIs
|
||||
@mock_apigatewayv2
|
||||
def test__get_apis__(self):
|
||||
# Generate ApiGatewayV2 Client
|
||||
apigatewayv2_client = client("apigatewayv2", region_name=AWS_REGION)
|
||||
# Create ApiGatewayV2 API
|
||||
apigatewayv2_client.create_api(Name="test-api", ProtocolType="HTTP")
|
||||
# ApiGatewayV2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigatewayv2 = ApiGatewayV2(audit_info)
|
||||
assert len(apigatewayv2.apis) == len(apigatewayv2_client.get_apis()["Items"])
|
||||
|
||||
# Test ApiGatewayV2 Get Authorizers
|
||||
@mock_apigatewayv2
|
||||
def test__get_authorizers__(self):
|
||||
# Generate ApiGatewayV2 Client
|
||||
apigatewayv2_client = client("apigatewayv2", region_name=AWS_REGION)
|
||||
# Create ApiGatewayV2 Rest API
|
||||
api = apigatewayv2_client.create_api(Name="test-api", ProtocolType="HTTP")
|
||||
# Create authorizer
|
||||
apigatewayv2_client.create_authorizer(
|
||||
ApiId=api["ApiId"],
|
||||
AuthorizerType="REQUEST",
|
||||
IdentitySource=[],
|
||||
Name="auth1",
|
||||
AuthorizerPayloadFormatVersion="2.0",
|
||||
)
|
||||
# ApiGatewayV2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigatewayv2 = ApiGatewayV2(audit_info)
|
||||
assert apigatewayv2.apis[0].authorizer is True
|
||||
|
||||
# Test ApiGatewayV2 Get Stages
|
||||
@mock_apigatewayv2
|
||||
def test__get_stages__(self):
|
||||
# Generate ApiGatewayV2 Client
|
||||
apigatewayv2_client = client("apigatewayv2", region_name=AWS_REGION)
|
||||
# Create ApiGatewayV2 Rest API and a deployment stage
|
||||
apigatewayv2_client.create_api(Name="test-api", ProtocolType="HTTP")
|
||||
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
apigatewayv2 = ApiGatewayV2(audit_info)
|
||||
assert apigatewayv2.apis[0].stages[0].logging is True
|
||||
@@ -0,0 +1,158 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.appstream.appstream_service import Fleet
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_appstream_fleet_default_internet_access_disabled:
|
||||
def test_no_fleets(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_default_internet_access_disabled.appstream_fleet_default_internet_access_disabled import (
|
||||
appstream_fleet_default_internet_access_disabled,
|
||||
)
|
||||
|
||||
check = appstream_fleet_default_internet_access_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_fleet_internet_access_enabled(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet",
|
||||
max_user_duration_in_seconds=900,
|
||||
disconnect_timeout_in_seconds=900,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_default_internet_access_disabled.appstream_fleet_default_internet_access_disabled import (
|
||||
appstream_fleet_default_internet_access_disabled,
|
||||
)
|
||||
|
||||
check = appstream_fleet_default_internet_access_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has default internet access enabled"
|
||||
)
|
||||
|
||||
def test_one_fleet_internet_access_disbaled(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet",
|
||||
max_user_duration_in_seconds=900,
|
||||
disconnect_timeout_in_seconds=900,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=False,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_default_internet_access_disabled.appstream_fleet_default_internet_access_disabled import (
|
||||
appstream_fleet_default_internet_access_disabled,
|
||||
)
|
||||
|
||||
check = appstream_fleet_default_internet_access_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has default internet access disabled"
|
||||
)
|
||||
|
||||
def test_two_fleets_internet_access_one_enabled_two_disabled(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet-1",
|
||||
max_user_duration_in_seconds=900,
|
||||
disconnect_timeout_in_seconds=900,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
fleet2 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet-2",
|
||||
max_user_duration_in_seconds=900,
|
||||
disconnect_timeout_in_seconds=900,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=False,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
appstream_client.fleets.append(fleet2)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_default_internet_access_disabled.appstream_fleet_default_internet_access_disabled import (
|
||||
appstream_fleet_default_internet_access_disabled,
|
||||
)
|
||||
|
||||
check = appstream_fleet_default_internet_access_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 2
|
||||
|
||||
for res in result:
|
||||
if res.resource_id == fleet1.name:
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has default internet access enabled"
|
||||
)
|
||||
if res.resource_id == fleet2.name:
|
||||
assert result[1].resource_arn == fleet2.arn
|
||||
assert result[1].region == fleet2.region
|
||||
assert result[1].resource_id == fleet2.name
|
||||
assert result[1].status == "PASS"
|
||||
assert (
|
||||
result[1].status_extended
|
||||
== f"Fleet {fleet2.name} has default internet access disabled"
|
||||
)
|
||||
@@ -0,0 +1,164 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.appstream.appstream_service import Fleet
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_appstream_fleet_maximum_session_duration:
|
||||
def test_no_fleets(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_maximum_session_duration.appstream_fleet_maximum_session_duration import (
|
||||
appstream_fleet_maximum_session_duration,
|
||||
)
|
||||
|
||||
check = appstream_fleet_maximum_session_duration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_fleet_maximum_session_duration_more_than_10_hours(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet",
|
||||
# 11 Hours
|
||||
max_user_duration_in_seconds=11 * 60 * 60,
|
||||
disconnect_timeout_in_seconds=900,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_maximum_session_duration.appstream_fleet_maximum_session_duration import (
|
||||
appstream_fleet_maximum_session_duration,
|
||||
)
|
||||
|
||||
check = appstream_fleet_maximum_session_duration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has the maximum session duration configured for more that 10 hours"
|
||||
)
|
||||
|
||||
def test_one_fleet_maximum_session_duration_less_than_10_hours(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet",
|
||||
# 9 Hours
|
||||
max_user_duration_in_seconds=9 * 60 * 60,
|
||||
disconnect_timeout_in_seconds=900,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_maximum_session_duration.appstream_fleet_maximum_session_duration import (
|
||||
appstream_fleet_maximum_session_duration,
|
||||
)
|
||||
|
||||
check = appstream_fleet_maximum_session_duration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has the maximum session duration configured for less that 10 hours"
|
||||
)
|
||||
|
||||
def test_two_fleets_one_maximum_session_duration_less_than_10_hours_on_more_than_10_hours(
|
||||
self,
|
||||
):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet-1",
|
||||
# 1 Hours
|
||||
max_user_duration_in_seconds=1 * 60 * 60,
|
||||
disconnect_timeout_in_seconds=900,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
fleet2 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet-2",
|
||||
# 24 Hours
|
||||
max_user_duration_in_seconds=24 * 60 * 60,
|
||||
disconnect_timeout_in_seconds=900,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=False,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
appstream_client.fleets.append(fleet2)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_maximum_session_duration.appstream_fleet_maximum_session_duration import (
|
||||
appstream_fleet_maximum_session_duration,
|
||||
)
|
||||
|
||||
check = appstream_fleet_maximum_session_duration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 2
|
||||
|
||||
for res in result:
|
||||
if res.resource_id == fleet1.name:
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has the maximum session duration configured for less that 10 hours"
|
||||
)
|
||||
if res.resource_id == fleet2.name:
|
||||
assert result[1].resource_arn == fleet2.arn
|
||||
assert result[1].region == fleet2.region
|
||||
assert result[1].resource_id == fleet2.name
|
||||
assert result[1].status == "FAIL"
|
||||
assert (
|
||||
result[1].status_extended
|
||||
== f"Fleet {fleet2.name} has the maximum session duration configured for more that 10 hours"
|
||||
)
|
||||
@@ -0,0 +1,164 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.appstream.appstream_service import Fleet
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_appstream_fleet_session_disconnect_timeout:
|
||||
def test_no_fleets(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_session_disconnect_timeout.appstream_fleet_session_disconnect_timeout import (
|
||||
appstream_fleet_session_disconnect_timeout,
|
||||
)
|
||||
|
||||
check = appstream_fleet_session_disconnect_timeout()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_fleet_session_disconnect_timeout_more_than_5_minutes(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet",
|
||||
max_user_duration_in_seconds=1 * 60 * 60,
|
||||
# 1 hour
|
||||
disconnect_timeout_in_seconds=1 * 60 * 60,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_session_disconnect_timeout.appstream_fleet_session_disconnect_timeout import (
|
||||
appstream_fleet_session_disconnect_timeout,
|
||||
)
|
||||
|
||||
check = appstream_fleet_session_disconnect_timeout()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has the session disconnect timeout set to more than 5 minutes"
|
||||
)
|
||||
|
||||
def test_one_fleet_session_disconnect_timeout_less_than_5_minutes(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet",
|
||||
max_user_duration_in_seconds=900,
|
||||
# 4 minutes
|
||||
disconnect_timeout_in_seconds=4 * 60,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_session_disconnect_timeout.appstream_fleet_session_disconnect_timeout import (
|
||||
appstream_fleet_session_disconnect_timeout,
|
||||
)
|
||||
|
||||
check = appstream_fleet_session_disconnect_timeout()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has the session disconnect timeout set to less than 5 minutes"
|
||||
)
|
||||
|
||||
def test_two_fleets_session_disconnect_timeout_less_than_5_minutes_one_more_than_5_minutes(
|
||||
self,
|
||||
):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet-1",
|
||||
max_user_duration_in_seconds=1 * 60 * 60,
|
||||
# 1 Hours
|
||||
disconnect_timeout_in_seconds=1 * 60 * 60,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
fleet2 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet-2",
|
||||
max_user_duration_in_seconds=24 * 60 * 60,
|
||||
# 3 minutes
|
||||
disconnect_timeout_in_seconds=3 * 60,
|
||||
idle_disconnect_timeout_in_seconds=900,
|
||||
enable_default_internet_access=False,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
appstream_client.fleets.append(fleet2)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_session_disconnect_timeout.appstream_fleet_session_disconnect_timeout import (
|
||||
appstream_fleet_session_disconnect_timeout,
|
||||
)
|
||||
|
||||
check = appstream_fleet_session_disconnect_timeout()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 2
|
||||
|
||||
for res in result:
|
||||
if res.resource_id == fleet1.name:
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has the session disconnect timeout set to more than 5 minutes"
|
||||
)
|
||||
if res.resource_id == fleet2.name:
|
||||
assert result[1].resource_arn == fleet2.arn
|
||||
assert result[1].region == fleet2.region
|
||||
assert result[1].resource_id == fleet2.name
|
||||
assert result[1].status == "PASS"
|
||||
assert (
|
||||
result[1].status_extended
|
||||
== f"Fleet {fleet2.name} has the session disconnect timeout set to less than 5 minutes"
|
||||
)
|
||||
@@ -0,0 +1,164 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.appstream.appstream_service import Fleet
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_appstream_fleet_session_idle_disconnect_timeout:
|
||||
def test_no_fleets(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_session_idle_disconnect_timeout.appstream_fleet_session_idle_disconnect_timeout import (
|
||||
appstream_fleet_session_idle_disconnect_timeout,
|
||||
)
|
||||
|
||||
check = appstream_fleet_session_idle_disconnect_timeout()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_fleet_session_idle_disconnect_timeout_more_than_10_minutes(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet",
|
||||
max_user_duration_in_seconds=1 * 60 * 60,
|
||||
disconnect_timeout_in_seconds=1 * 60 * 60,
|
||||
# 15 minutes
|
||||
idle_disconnect_timeout_in_seconds=15 * 60,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_session_idle_disconnect_timeout.appstream_fleet_session_idle_disconnect_timeout import (
|
||||
appstream_fleet_session_idle_disconnect_timeout,
|
||||
)
|
||||
|
||||
check = appstream_fleet_session_idle_disconnect_timeout()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has the session idle disconnect timeout set to more than 10 minutes"
|
||||
)
|
||||
|
||||
def test_one_fleet_session_idle_disconnect_timeout_less_than_10_minutes(self):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet",
|
||||
max_user_duration_in_seconds=900,
|
||||
disconnect_timeout_in_seconds=4 * 60,
|
||||
# 8 minutes
|
||||
idle_disconnect_timeout_in_seconds=8 * 60,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_session_idle_disconnect_timeout.appstream_fleet_session_idle_disconnect_timeout import (
|
||||
appstream_fleet_session_idle_disconnect_timeout,
|
||||
)
|
||||
|
||||
check = appstream_fleet_session_idle_disconnect_timeout()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has the session idle disconnect timeout set to less than 10 minutes"
|
||||
)
|
||||
|
||||
def test_two_fleets_session_idle_disconnect_timeout_than_10_minutes_one_more_than_10_minutes(
|
||||
self,
|
||||
):
|
||||
appstream_client = mock.MagicMock
|
||||
appstream_client.fleets = []
|
||||
fleet1 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet-1",
|
||||
max_user_duration_in_seconds=1 * 60 * 60,
|
||||
disconnect_timeout_in_seconds=3 * 60,
|
||||
# 5 minutes
|
||||
idle_disconnect_timeout_in_seconds=5 * 60,
|
||||
enable_default_internet_access=True,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
fleet2 = Fleet(
|
||||
arn="arn",
|
||||
name="test-fleet-2",
|
||||
max_user_duration_in_seconds=24 * 60 * 60,
|
||||
disconnect_timeout_in_seconds=3 * 60,
|
||||
# 45 minutes
|
||||
idle_disconnect_timeout_in_seconds=45 * 60,
|
||||
enable_default_internet_access=False,
|
||||
region=AWS_REGION,
|
||||
)
|
||||
|
||||
appstream_client.fleets.append(fleet1)
|
||||
appstream_client.fleets.append(fleet2)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.AppStream",
|
||||
new=appstream_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.appstream.appstream_fleet_session_idle_disconnect_timeout.appstream_fleet_session_idle_disconnect_timeout import (
|
||||
appstream_fleet_session_idle_disconnect_timeout,
|
||||
)
|
||||
|
||||
check = appstream_fleet_session_idle_disconnect_timeout()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 2
|
||||
|
||||
for res in result:
|
||||
if res.resource_id == fleet1.name:
|
||||
assert result[0].resource_arn == fleet1.arn
|
||||
assert result[0].region == fleet1.region
|
||||
assert result[0].resource_id == fleet1.name
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Fleet {fleet1.name} has the session idle disconnect timeout set to less than 10 minutes"
|
||||
)
|
||||
if res.resource_id == fleet2.name:
|
||||
assert result[1].resource_arn == fleet2.arn
|
||||
assert result[1].region == fleet2.region
|
||||
assert result[1].resource_id == fleet2.name
|
||||
assert result[1].status == "FAIL"
|
||||
assert (
|
||||
result[1].status_extended
|
||||
== f"Fleet {fleet2.name} has the session idle disconnect timeout set to more than 10 minutes"
|
||||
)
|
||||
104
tests/providers/aws/services/appstream/appstream_service_test.py
Normal file
104
tests/providers/aws/services/appstream/appstream_service_test.py
Normal file
@@ -0,0 +1,104 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
import botocore
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.appstream.appstream_service import AppStream
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
# Mocking Access Analyzer Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
"""
|
||||
We have to mock every AWS API call using Boto3
|
||||
|
||||
As you can see the operation_name has the list_analyzers snake_case form but
|
||||
we are using the ListAnalyzers form.
|
||||
Rationale -> https://github.com/boto/botocore/blob/develop/botocore/client.py#L810:L816
|
||||
"""
|
||||
if operation_name == "DescribeFleets":
|
||||
return {
|
||||
"Fleets": [
|
||||
{
|
||||
"Arn": f"arn:aws:appstream:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:fleet/test-prowler3-0",
|
||||
"Name": "test-prowler3-0",
|
||||
"MaxUserDurationInSeconds": 100,
|
||||
"DisconnectTimeoutInSeconds": 900,
|
||||
"IdleDisconnectTimeoutInSeconds": 900,
|
||||
"EnableDefaultInternetAccess": False,
|
||||
},
|
||||
{
|
||||
"Arn": f"arn:aws:appstream:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:fleet/test-prowler3-1",
|
||||
"Name": "test-prowler3-1",
|
||||
"MaxUserDurationInSeconds": 57600,
|
||||
"DisconnectTimeoutInSeconds": 900,
|
||||
"IdleDisconnectTimeoutInSeconds": 900,
|
||||
"EnableDefaultInternetAccess": True,
|
||||
},
|
||||
]
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
# Mock generate_regional_clients()
|
||||
def mock_generate_regional_clients(service, audit_info):
|
||||
regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION)
|
||||
regional_client.region = AWS_REGION
|
||||
return {AWS_REGION: regional_client}
|
||||
|
||||
|
||||
# Patch every AWS call using Boto3 and generate_regional_clients to have 1 client
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
@patch(
|
||||
"prowler.providers.aws.services.appstream.appstream_service.generate_regional_clients",
|
||||
new=mock_generate_regional_clients,
|
||||
)
|
||||
class Test_AppStream_Service:
|
||||
# Test AppStream Client
|
||||
def test__get_client__(self):
|
||||
appstream = AppStream(current_audit_info)
|
||||
assert appstream.regional_clients[AWS_REGION].__class__.__name__ == "AppStream"
|
||||
|
||||
# Test AppStream Session
|
||||
def test__get_session__(self):
|
||||
appstream = AppStream(current_audit_info)
|
||||
assert appstream.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test AppStream Session
|
||||
def test__get_service__(self):
|
||||
appstream = AppStream(current_audit_info)
|
||||
assert appstream.service == "appstream"
|
||||
|
||||
def test__describe_fleets__(self):
|
||||
# Set partition for the service
|
||||
current_audit_info.audited_partition = "aws"
|
||||
appstream = AppStream(current_audit_info)
|
||||
assert len(appstream.fleets) == 2
|
||||
|
||||
assert (
|
||||
appstream.fleets[0].arn
|
||||
== f"arn:aws:appstream:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:fleet/test-prowler3-0"
|
||||
)
|
||||
assert appstream.fleets[0].name == "test-prowler3-0"
|
||||
assert appstream.fleets[0].max_user_duration_in_seconds == 100
|
||||
assert appstream.fleets[0].disconnect_timeout_in_seconds == 900
|
||||
assert appstream.fleets[0].idle_disconnect_timeout_in_seconds == 900
|
||||
assert appstream.fleets[0].enable_default_internet_access is False
|
||||
assert appstream.fleets[0].region == AWS_REGION
|
||||
|
||||
assert (
|
||||
appstream.fleets[1].arn
|
||||
== f"arn:aws:appstream:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:fleet/test-prowler3-1"
|
||||
)
|
||||
assert appstream.fleets[1].name == "test-prowler3-1"
|
||||
assert appstream.fleets[1].max_user_duration_in_seconds == 57600
|
||||
assert appstream.fleets[1].disconnect_timeout_in_seconds == 900
|
||||
assert appstream.fleets[1].idle_disconnect_timeout_in_seconds == 900
|
||||
assert appstream.fleets[1].enable_default_internet_access is True
|
||||
assert appstream.fleets[1].region == AWS_REGION
|
||||
@@ -0,0 +1,194 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_autoscaling
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_autoscaling_find_secrets_ec2_launch_configuration:
|
||||
@mock_autoscaling
|
||||
def test_no_autoscaling(self):
|
||||
autoscaling_client = client("autoscaling", region_name=AWS_REGION)
|
||||
autoscaling_client.launch_configurations = []
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_service import (
|
||||
AutoScaling,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_client",
|
||||
new=AutoScaling(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration import (
|
||||
autoscaling_find_secrets_ec2_launch_configuration,
|
||||
)
|
||||
|
||||
check = autoscaling_find_secrets_ec2_launch_configuration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_autoscaling
|
||||
def test_one_autoscaling_with_no_secrets(self):
|
||||
# Include launch_configurations to check
|
||||
autoscaling_client = client("autoscaling", region_name=AWS_REGION)
|
||||
autoscaling_client.create_launch_configuration(
|
||||
LaunchConfigurationName="tester",
|
||||
ImageId="ami-12c6146b",
|
||||
InstanceType="t1.micro",
|
||||
KeyName="the_keys",
|
||||
SecurityGroups=["default", "default2"],
|
||||
UserData="This is some user_data",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_service import (
|
||||
AutoScaling,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_client",
|
||||
new=AutoScaling(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration import (
|
||||
autoscaling_find_secrets_ec2_launch_configuration,
|
||||
)
|
||||
|
||||
check = autoscaling_find_secrets_ec2_launch_configuration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No secrets found in autoscaling tester User Data."
|
||||
)
|
||||
assert result[0].resource_id == "tester"
|
||||
|
||||
@mock_autoscaling
|
||||
def test_one_autoscaling_with_secrets(self):
|
||||
# Include launch_configurations to check
|
||||
autoscaling_client = client("autoscaling", region_name=AWS_REGION)
|
||||
autoscaling_client.create_launch_configuration(
|
||||
LaunchConfigurationName="tester",
|
||||
ImageId="ami-12c6146b",
|
||||
InstanceType="t1.micro",
|
||||
KeyName="the_keys",
|
||||
SecurityGroups=["default", "default2"],
|
||||
UserData="DB_PASSWORD=foobar123",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_service import (
|
||||
AutoScaling,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_client",
|
||||
new=AutoScaling(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration import (
|
||||
autoscaling_find_secrets_ec2_launch_configuration,
|
||||
)
|
||||
|
||||
check = autoscaling_find_secrets_ec2_launch_configuration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Potential secret found in autoscaling tester User Data."
|
||||
)
|
||||
assert result[0].resource_id == "tester"
|
||||
|
||||
@mock_autoscaling
|
||||
def test_one_autoscaling_file_with_secrets(self):
|
||||
# Include launch_configurations to check
|
||||
f = open(
|
||||
"prowler/providers/aws/services/autoscaling/autoscaling_find_secrets_ec2_launch_configuration/fixtures/fixture",
|
||||
"r",
|
||||
)
|
||||
secrets = f.read()
|
||||
autoscaling_client = client("autoscaling", region_name=AWS_REGION)
|
||||
autoscaling_client.create_launch_configuration(
|
||||
LaunchConfigurationName="tester",
|
||||
ImageId="ami-12c6146b",
|
||||
InstanceType="t1.micro",
|
||||
KeyName="the_keys",
|
||||
SecurityGroups=["default", "default2"],
|
||||
UserData=secrets,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_service import (
|
||||
AutoScaling,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_client",
|
||||
new=AutoScaling(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration import (
|
||||
autoscaling_find_secrets_ec2_launch_configuration,
|
||||
)
|
||||
|
||||
check = autoscaling_find_secrets_ec2_launch_configuration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Potential secret found in autoscaling tester User Data."
|
||||
)
|
||||
assert result[0].resource_id == "tester"
|
||||
|
||||
@mock_autoscaling
|
||||
def test_one_launch_configurations_without_user_data(self):
|
||||
# Include launch_configurations to check
|
||||
autoscaling_client = client("autoscaling", region_name=AWS_REGION)
|
||||
autoscaling_client.create_launch_configuration(
|
||||
LaunchConfigurationName="tester",
|
||||
ImageId="ami-12c6146b",
|
||||
InstanceType="t1.micro",
|
||||
KeyName="the_keys",
|
||||
SecurityGroups=["default", "default2"],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_service import (
|
||||
AutoScaling,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_client",
|
||||
new=AutoScaling(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration import (
|
||||
autoscaling_find_secrets_ec2_launch_configuration,
|
||||
)
|
||||
|
||||
check = autoscaling_find_secrets_ec2_launch_configuration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No secrets found in autoscaling tester since User Data is empty."
|
||||
)
|
||||
assert result[0].resource_id == "tester"
|
||||
@@ -0,0 +1,100 @@
|
||||
from base64 import b64decode
|
||||
|
||||
from boto3 import client, session
|
||||
from moto import mock_autoscaling
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.autoscaling.autoscaling_service import AutoScaling
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_AutoScaling_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test AutoScaling Service
|
||||
@mock_autoscaling
|
||||
def test_service(self):
|
||||
# AutoScaling client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
autoscaling = AutoScaling(audit_info)
|
||||
assert autoscaling.service == "autoscaling"
|
||||
|
||||
# Test AutoScaling Client
|
||||
@mock_autoscaling
|
||||
def test_client(self):
|
||||
# AutoScaling client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
autoscaling = AutoScaling(audit_info)
|
||||
for regional_client in autoscaling.regional_clients.values():
|
||||
assert regional_client.__class__.__name__ == "AutoScaling"
|
||||
|
||||
# Test AutoScaling Session
|
||||
@mock_autoscaling
|
||||
def test__get_session__(self):
|
||||
# AutoScaling client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
autoscaling = AutoScaling(audit_info)
|
||||
assert autoscaling.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test AutoScaling Session
|
||||
@mock_autoscaling
|
||||
def test_audited_account(self):
|
||||
# AutoScaling client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
autoscaling = AutoScaling(audit_info)
|
||||
assert autoscaling.audited_account == AWS_ACCOUNT_NUMBER
|
||||
|
||||
# Test AutoScaling Get APIs
|
||||
@mock_autoscaling
|
||||
def test__describe_launch_configurations__(self):
|
||||
# Generate AutoScaling Client
|
||||
autoscaling_client = client("autoscaling", region_name=AWS_REGION)
|
||||
# Create AutoScaling API
|
||||
autoscaling_client.create_launch_configuration(
|
||||
LaunchConfigurationName="tester1",
|
||||
ImageId="ami-12c6146b",
|
||||
InstanceType="t1.micro",
|
||||
KeyName="the_keys",
|
||||
SecurityGroups=["default", "default2"],
|
||||
UserData="DB_PASSWORD=foobar123",
|
||||
)
|
||||
autoscaling_client.create_launch_configuration(
|
||||
LaunchConfigurationName="tester2",
|
||||
ImageId="ami-12c6146b",
|
||||
InstanceType="t1.micro",
|
||||
KeyName="the_keys",
|
||||
SecurityGroups=["default", "default2"],
|
||||
)
|
||||
# AutoScaling client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
autoscaling = AutoScaling(audit_info)
|
||||
assert len(autoscaling.launch_configurations) == 2
|
||||
assert autoscaling.launch_configurations[0].name == "tester1"
|
||||
assert (
|
||||
b64decode(autoscaling.launch_configurations[0].user_data).decode("utf-8")
|
||||
== "DB_PASSWORD=foobar123"
|
||||
)
|
||||
assert autoscaling.launch_configurations[0].image_id == "ami-12c6146b"
|
||||
assert autoscaling.launch_configurations[1].image_id == "ami-12c6146b"
|
||||
assert autoscaling.launch_configurations[1].name == "tester2"
|
||||
@@ -0,0 +1,217 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client, session
|
||||
from mock import patch
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.awslambda.awslambda_service import Function
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
# Mock generate_regional_clients()
|
||||
def mock_generate_regional_clients(service, audit_info):
|
||||
regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION)
|
||||
regional_client.region = AWS_REGION
|
||||
return {AWS_REGION: regional_client}
|
||||
|
||||
|
||||
# Patch every AWS call using Boto3 and generate_regional_clients to have 1 client
|
||||
@patch(
|
||||
"prowler.providers.aws.services.accessanalyzer.accessanalyzer_service.generate_regional_clients",
|
||||
new=mock_generate_regional_clients,
|
||||
)
|
||||
class Test_awslambda_function_invoke_api_operations_cloudtrail_logging_enabled:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=None,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
@mock_cloudtrail
|
||||
def test_no_functions(self):
|
||||
lambda_client = mock.MagicMock
|
||||
lambda_client.functions = {}
|
||||
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
self.set_mocked_audit_info(),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(self.set_mocked_audit_info()),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled import (
|
||||
awslambda_function_invoke_api_operations_cloudtrail_logging_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
awslambda_function_invoke_api_operations_cloudtrail_logging_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_lambda_not_recorded_by_cloudtrail(self):
|
||||
# Lambda Client
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "python3.9"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_client.functions = {
|
||||
function_name: Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
)
|
||||
}
|
||||
|
||||
# CloudTrail Client
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
trail_name = "test-trail"
|
||||
bucket_name = "test-bucket"
|
||||
s3_client.create_bucket(Bucket=bucket_name)
|
||||
cloudtrail_client.create_trail(
|
||||
Name=trail_name, S3BucketName=bucket_name, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
self.set_mocked_audit_info(),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(self.set_mocked_audit_info()),
|
||||
):
|
||||
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled import (
|
||||
awslambda_function_invoke_api_operations_cloudtrail_logging_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
awslambda_function_invoke_api_operations_cloudtrail_logging_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} is not recorded by CloudTrail"
|
||||
)
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_lambda_recorded_by_cloudtrail(self):
|
||||
# Lambda Client
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "python3.9"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_client.functions = {
|
||||
function_name: Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
)
|
||||
}
|
||||
|
||||
# CloudTrail Client
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
trail_name = "test-trail"
|
||||
bucket_name = "test-bucket"
|
||||
s3_client.create_bucket(Bucket=bucket_name)
|
||||
cloudtrail_client.create_trail(
|
||||
Name=trail_name, S3BucketName=bucket_name, IsMultiRegionTrail=False
|
||||
)
|
||||
_ = cloudtrail_client.put_event_selectors(
|
||||
TrailName=trail_name,
|
||||
EventSelectors=[
|
||||
{
|
||||
"ReadWriteType": "All",
|
||||
"IncludeManagementEvents": True,
|
||||
"DataResources": [
|
||||
{"Type": "AWS::Lambda::Function", "Values": [function_arn]}
|
||||
],
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
|
||||
self.set_mocked_audit_info(),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(self.set_mocked_audit_info()),
|
||||
):
|
||||
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled.awslambda_function_invoke_api_operations_cloudtrail_logging_enabled import (
|
||||
awslambda_function_invoke_api_operations_cloudtrail_logging_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
awslambda_function_invoke_api_operations_cloudtrail_logging_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} is recorded by CloudTrail {trail_name}"
|
||||
)
|
||||
@@ -0,0 +1,127 @@
|
||||
import zipfile
|
||||
from unittest import mock
|
||||
|
||||
from awslambda_service_test import create_zip_file
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.awslambda.awslambda_service import (
|
||||
Function,
|
||||
LambdaCode,
|
||||
)
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_awslambda_function_no_secrets_in_code:
|
||||
def test_no_functions(self):
|
||||
lambda_client = mock.MagicMock
|
||||
lambda_client.functions = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_no_secrets_in_code.awslambda_function_no_secrets_in_code import (
|
||||
awslambda_function_no_secrets_in_code,
|
||||
)
|
||||
|
||||
check = awslambda_function_no_secrets_in_code()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_function_code_with_secrets(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
code_with_secrets = """
|
||||
def lambda_handler(event, context):
|
||||
db_password = "test-password"
|
||||
print("custom log event")
|
||||
return event
|
||||
"""
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
code=LambdaCode(
|
||||
location="",
|
||||
code_zip=zipfile.ZipFile(create_zip_file(code_with_secrets)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_no_secrets_in_code.awslambda_function_no_secrets_in_code import (
|
||||
awslambda_function_no_secrets_in_code,
|
||||
)
|
||||
|
||||
check = awslambda_function_no_secrets_in_code()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Potential secret found in Lambda function {function_name} code"
|
||||
)
|
||||
|
||||
def test_function_code_without_secrets(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
code_with_secrets = """
|
||||
def lambda_handler(event, context):
|
||||
print("custom log event")
|
||||
return event
|
||||
"""
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
code=LambdaCode(
|
||||
location="",
|
||||
code_zip=zipfile.ZipFile(create_zip_file(code_with_secrets)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_no_secrets_in_code.awslambda_function_no_secrets_in_code import (
|
||||
awslambda_function_no_secrets_in_code,
|
||||
)
|
||||
|
||||
check = awslambda_function_no_secrets_in_code()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"No secrets found in Lambda function {function_name} code"
|
||||
)
|
||||
@@ -0,0 +1,146 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.awslambda.awslambda_service import Function
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_awslambda_function_no_secrets_in_variables:
|
||||
def test_no_functions(self):
|
||||
lambda_client = mock.MagicMock
|
||||
lambda_client.functions = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_no_secrets_in_variables.awslambda_function_no_secrets_in_variables import (
|
||||
awslambda_function_no_secrets_in_variables,
|
||||
)
|
||||
|
||||
check = awslambda_function_no_secrets_in_variables()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_function_no_variables(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_no_secrets_in_variables.awslambda_function_no_secrets_in_variables import (
|
||||
awslambda_function_no_secrets_in_variables,
|
||||
)
|
||||
|
||||
check = awslambda_function_no_secrets_in_variables()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"No secrets found in Lambda function {function_name} variables"
|
||||
)
|
||||
|
||||
def test_function_secrets_in_variables(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
environment={"db_password": "test-password"},
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_no_secrets_in_variables.awslambda_function_no_secrets_in_variables import (
|
||||
awslambda_function_no_secrets_in_variables,
|
||||
)
|
||||
|
||||
check = awslambda_function_no_secrets_in_variables()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Potential secret found in Lambda function {function_name} variables"
|
||||
)
|
||||
|
||||
def test_function_no_secrets_in_variables(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
environment={"db_username": "test-user"},
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_no_secrets_in_variables.awslambda_function_no_secrets_in_variables import (
|
||||
awslambda_function_no_secrets_in_variables,
|
||||
)
|
||||
|
||||
check = awslambda_function_no_secrets_in_variables()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"No secrets found in Lambda function {function_name} variables"
|
||||
)
|
||||
@@ -0,0 +1,189 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.awslambda.awslambda_service import Function
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_awslambda_function_not_publicly_accessible:
|
||||
def test_no_functions(self):
|
||||
lambda_client = mock.MagicMock
|
||||
lambda_client.functions = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_not_publicly_accessible.awslambda_function_not_publicly_accessible import (
|
||||
awslambda_function_not_publicly_accessible,
|
||||
)
|
||||
|
||||
check = awslambda_function_not_publicly_accessible()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_function_public(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_policy = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "public-access",
|
||||
"Principal": {"AWS": ["*", DEFAULT_ACCOUNT_ID]},
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"lambda:InvokeFunction",
|
||||
],
|
||||
"Resource": [function_arn],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
policy=lambda_policy,
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_not_publicly_accessible.awslambda_function_not_publicly_accessible import (
|
||||
awslambda_function_not_publicly_accessible,
|
||||
)
|
||||
|
||||
check = awslambda_function_not_publicly_accessible()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} has a policy resource-based policy with public access"
|
||||
)
|
||||
|
||||
def test_function_not_public(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_policy = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "public-access",
|
||||
"Principal": {"AWS": [DEFAULT_ACCOUNT_ID]},
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"lambda:InvokeFunction",
|
||||
],
|
||||
"Resource": [function_arn],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
policy=lambda_policy,
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_not_publicly_accessible.awslambda_function_not_publicly_accessible import (
|
||||
awslambda_function_not_publicly_accessible,
|
||||
)
|
||||
|
||||
check = awslambda_function_not_publicly_accessible()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} has a policy resource-based policy not public"
|
||||
)
|
||||
|
||||
def test_function_public_with_canonical(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_policy = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "public-access",
|
||||
"Principal": {"CanonicalUser": ["*"]},
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"lambda:InvokeFunction",
|
||||
],
|
||||
"Resource": [function_arn],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
policy=lambda_policy,
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_not_publicly_accessible.awslambda_function_not_publicly_accessible import (
|
||||
awslambda_function_not_publicly_accessible,
|
||||
)
|
||||
|
||||
check = awslambda_function_not_publicly_accessible()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} has a policy resource-based policy with public access"
|
||||
)
|
||||
@@ -0,0 +1,163 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.awslambda.awslambda_service import (
|
||||
AuthType,
|
||||
Function,
|
||||
URLConfig,
|
||||
URLConfigCORS,
|
||||
)
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_awslambda_function_url_cors_policy:
|
||||
def test_no_functions(self):
|
||||
lambda_client = mock.MagicMock
|
||||
lambda_client.functions = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_url_cors_policy.awslambda_function_url_cors_policy import (
|
||||
awslambda_function_url_cors_policy,
|
||||
)
|
||||
|
||||
check = awslambda_function_url_cors_policy()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_function_cors_asterisk(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
url_config=URLConfig(
|
||||
auth_type=AuthType.NONE,
|
||||
url="",
|
||||
cors_config=URLConfigCORS(allow_origins=["*"]),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_url_cors_policy.awslambda_function_url_cors_policy import (
|
||||
awslambda_function_url_cors_policy,
|
||||
)
|
||||
|
||||
check = awslambda_function_url_cors_policy()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} URL has a wide CORS configuration"
|
||||
)
|
||||
|
||||
def test_function_cors_not_wide(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "python3.9"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
url_config=URLConfig(
|
||||
auth_type=AuthType.AWS_IAM,
|
||||
url="",
|
||||
cors_config=URLConfigCORS(allow_origins=["https://example.com"]),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_url_cors_policy.awslambda_function_url_cors_policy import (
|
||||
awslambda_function_url_cors_policy,
|
||||
)
|
||||
|
||||
check = awslambda_function_url_cors_policy()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} has not a wide CORS configuration"
|
||||
)
|
||||
|
||||
def test_function_cors_wide_with_two_origins(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "python3.9"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
url_config=URLConfig(
|
||||
auth_type=AuthType.AWS_IAM,
|
||||
url="",
|
||||
cors_config=URLConfigCORS(
|
||||
allow_origins=["https://example.com", "*"]
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_url_cors_policy.awslambda_function_url_cors_policy import (
|
||||
awslambda_function_url_cors_policy,
|
||||
)
|
||||
|
||||
check = awslambda_function_url_cors_policy()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} URL has a wide CORS configuration"
|
||||
)
|
||||
@@ -0,0 +1,118 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.awslambda.awslambda_service import (
|
||||
AuthType,
|
||||
Function,
|
||||
URLConfig,
|
||||
URLConfigCORS,
|
||||
)
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_awslambda_function_url_public:
|
||||
def test_no_functions(self):
|
||||
lambda_client = mock.MagicMock
|
||||
lambda_client.functions = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_url_public.awslambda_function_url_public import (
|
||||
awslambda_function_url_public,
|
||||
)
|
||||
|
||||
check = awslambda_function_url_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_function_public_url(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
url_config=URLConfig(
|
||||
auth_type=AuthType.NONE,
|
||||
url="",
|
||||
cors_config=URLConfigCORS(allow_origins=[]),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_url_public.awslambda_function_url_public import (
|
||||
awslambda_function_url_public,
|
||||
)
|
||||
|
||||
check = awslambda_function_url_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} has a publicly accessible function URL"
|
||||
)
|
||||
|
||||
def test_function_private_url(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "python3.9"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
url_config=URLConfig(
|
||||
auth_type=AuthType.AWS_IAM,
|
||||
url="",
|
||||
cors_config=URLConfigCORS(allow_origins=[]),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_url_public.awslambda_function_url_public import (
|
||||
awslambda_function_url_public,
|
||||
)
|
||||
|
||||
check = awslambda_function_url_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} has not a publicly accessible function URL"
|
||||
)
|
||||
@@ -0,0 +1,126 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.awslambda.awslambda_service import Function
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
def mock_get_config_var(config_var: str):
|
||||
return [
|
||||
"python3.6",
|
||||
"python2.7",
|
||||
"nodejs4.3",
|
||||
"nodejs4.3-edge",
|
||||
"nodejs6.10",
|
||||
"nodejs",
|
||||
"nodejs8.10",
|
||||
"nodejs10.x",
|
||||
"dotnetcore1.0",
|
||||
"dotnetcore2.0",
|
||||
"dotnetcore2.1",
|
||||
"ruby2.5",
|
||||
]
|
||||
|
||||
|
||||
class Test_awslambda_function_using_supported_runtimes:
|
||||
def test_no_functions(self):
|
||||
lambda_client = mock.MagicMock
|
||||
lambda_client.functions = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_using_supported_runtimes.awslambda_function_using_supported_runtimes import (
|
||||
awslambda_function_using_supported_runtimes,
|
||||
)
|
||||
|
||||
check = awslambda_function_using_supported_runtimes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_function_obsolete_runtime(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "nodejs4.3"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_function_using_supported_runtimes.awslambda_function_using_supported_runtimes.get_config_var",
|
||||
new=mock_get_config_var,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_using_supported_runtimes.awslambda_function_using_supported_runtimes import (
|
||||
awslambda_function_using_supported_runtimes,
|
||||
)
|
||||
|
||||
check = awslambda_function_using_supported_runtimes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} is using {function_runtime} which is obsolete"
|
||||
)
|
||||
|
||||
def test_function_supported_runtime(self):
|
||||
lambda_client = mock.MagicMock
|
||||
function_name = "test-lambda"
|
||||
function_runtime = "python3.9"
|
||||
function_arn = (
|
||||
f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function/{function_name}"
|
||||
)
|
||||
lambda_client.functions = {
|
||||
"function_name": Function(
|
||||
name=function_name,
|
||||
arn=function_arn,
|
||||
region=AWS_REGION,
|
||||
runtime=function_runtime,
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.Lambda",
|
||||
new=lambda_client,
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_function_using_supported_runtimes.awslambda_function_using_supported_runtimes.get_config_var",
|
||||
new=mock_get_config_var,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.awslambda.awslambda_function_using_supported_runtimes.awslambda_function_using_supported_runtimes import (
|
||||
awslambda_function_using_supported_runtimes,
|
||||
)
|
||||
|
||||
check = awslambda_function_using_supported_runtimes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == function_name
|
||||
assert result[0].resource_arn == function_arn
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Lambda function {function_name} is using {function_runtime} which is supported"
|
||||
)
|
||||
227
tests/providers/aws/services/awslambda/awslambda_service_test.py
Normal file
227
tests/providers/aws/services/awslambda/awslambda_service_test.py
Normal file
@@ -0,0 +1,227 @@
|
||||
import io
|
||||
import os
|
||||
import tempfile
|
||||
import zipfile
|
||||
from re import search
|
||||
from unittest.mock import patch
|
||||
|
||||
import mock
|
||||
from boto3 import client, resource, session
|
||||
from moto import mock_iam, mock_lambda, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.awslambda.awslambda_service import AuthType, Lambda
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
def create_zip_file(code: str = "") -> io.BytesIO:
|
||||
zip_output = io.BytesIO()
|
||||
zip_file = zipfile.ZipFile(zip_output, "w", zipfile.ZIP_DEFLATED)
|
||||
if not code:
|
||||
zip_file.writestr(
|
||||
"lambda_function.py",
|
||||
"""
|
||||
def lambda_handler(event, context):
|
||||
print("custom log event")
|
||||
return event
|
||||
""",
|
||||
)
|
||||
else:
|
||||
zip_file.writestr("lambda_function.py", code)
|
||||
zip_file.close()
|
||||
zip_output.seek(0)
|
||||
return zip_output
|
||||
|
||||
|
||||
def mock_request_get(_):
|
||||
"""Mock requests.get() to get the Lambda Code in Zip Format"""
|
||||
mock_resp = mock.MagicMock
|
||||
mock_resp.status_code = 200
|
||||
mock_resp.content = create_zip_file().read()
|
||||
return mock_resp
|
||||
|
||||
|
||||
# Mock generate_regional_clients()
|
||||
def mock_generate_regional_clients(service, audit_info):
|
||||
regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION)
|
||||
regional_client.region = AWS_REGION
|
||||
return {AWS_REGION: regional_client}
|
||||
|
||||
|
||||
@patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.generate_regional_clients",
|
||||
new=mock_generate_regional_clients,
|
||||
)
|
||||
class Test_Lambda_Service:
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=DEFAULT_ACCOUNT_ID,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test Lambda Client
|
||||
def test__get_client__(self):
|
||||
awslambda = Lambda(current_audit_info)
|
||||
assert awslambda.regional_clients[AWS_REGION].__class__.__name__ == "Lambda"
|
||||
|
||||
# Test Lambda Session
|
||||
def test__get_session__(self):
|
||||
awslambda = Lambda(current_audit_info)
|
||||
assert awslambda.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test Lambda Service
|
||||
def test__get_service__(self):
|
||||
awslambda = Lambda(current_audit_info)
|
||||
assert awslambda.service == "lambda"
|
||||
|
||||
@mock_lambda
|
||||
@mock_iam
|
||||
@mock_s3
|
||||
def test__list_functions__(self):
|
||||
# Create IAM Lambda Role
|
||||
iam_client = client("iam", region_name=AWS_REGION)
|
||||
iam_role = iam_client.create_role(
|
||||
RoleName="test-lambda-role",
|
||||
AssumeRolePolicyDocument="test-policy",
|
||||
Path="/",
|
||||
)["Role"]["Arn"]
|
||||
# Create S3 Bucket
|
||||
s3_client = resource("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(
|
||||
Bucket="test-bucket",
|
||||
CreateBucketConfiguration={"LocationConstraint": AWS_REGION},
|
||||
)
|
||||
# Create Test Lambda
|
||||
lambda_client = client("lambda", region_name=AWS_REGION)
|
||||
lambda_name = "test-lambda"
|
||||
resp = lambda_client.create_function(
|
||||
FunctionName=lambda_name,
|
||||
Runtime="python3.7",
|
||||
Role=iam_role,
|
||||
Handler="lambda_function.lambda_handler",
|
||||
Code={"ZipFile": create_zip_file().read()},
|
||||
Description="test lambda function",
|
||||
Timeout=3,
|
||||
MemorySize=128,
|
||||
PackageType="ZIP",
|
||||
Publish=True,
|
||||
VpcConfig={
|
||||
"SecurityGroupIds": ["sg-123abc"],
|
||||
"SubnetIds": ["subnet-123abc"],
|
||||
},
|
||||
Environment={"Variables": {"db-password": "test-password"}},
|
||||
)
|
||||
# Update Lambda Policy
|
||||
lambda_policy = {
|
||||
"Version": "2012-10-17",
|
||||
"Id": "default",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "lambda:GetFunction",
|
||||
"Principal": "*",
|
||||
"Effect": "Allow",
|
||||
"Resource": f"arn:aws:lambda:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:function:{lambda_name}",
|
||||
"Sid": "test",
|
||||
}
|
||||
],
|
||||
}
|
||||
_ = lambda_client.add_permission(
|
||||
FunctionName=lambda_name,
|
||||
StatementId="test",
|
||||
Action="lambda:GetFunction",
|
||||
Principal="*",
|
||||
)
|
||||
# Create Function URL Config
|
||||
_ = lambda_client.create_function_url_config(
|
||||
FunctionName=lambda_name,
|
||||
AuthType=AuthType.AWS_IAM.value,
|
||||
Cors={
|
||||
"AllowCredentials": True,
|
||||
"AllowHeaders": [
|
||||
"string",
|
||||
],
|
||||
"AllowMethods": [
|
||||
"string",
|
||||
],
|
||||
"AllowOrigins": [
|
||||
"*",
|
||||
],
|
||||
"ExposeHeaders": [
|
||||
"string",
|
||||
],
|
||||
"MaxAge": 123,
|
||||
},
|
||||
)
|
||||
|
||||
lambda_arn = resp["FunctionArn"]
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.awslambda.awslambda_service.requests.get",
|
||||
new=mock_request_get,
|
||||
):
|
||||
awslambda = Lambda(self.set_mocked_audit_info())
|
||||
|
||||
assert awslambda.functions
|
||||
assert awslambda.functions[lambda_name].name == lambda_name
|
||||
assert awslambda.functions[lambda_name].arn == lambda_arn
|
||||
assert awslambda.functions[lambda_name].runtime == "python3.7"
|
||||
assert awslambda.functions[lambda_name].environment == {
|
||||
"db-password": "test-password"
|
||||
}
|
||||
assert awslambda.functions[lambda_name].region == AWS_REGION
|
||||
assert awslambda.functions[lambda_name].policy == lambda_policy
|
||||
|
||||
assert awslambda.functions[lambda_name].code
|
||||
assert search(
|
||||
f"s3://awslambda-{AWS_REGION}-tasks.s3-{AWS_REGION}.amazonaws.com",
|
||||
awslambda.functions[lambda_name].code.location,
|
||||
)
|
||||
|
||||
assert awslambda.functions[lambda_name].url_config
|
||||
assert (
|
||||
awslambda.functions[lambda_name].url_config.auth_type
|
||||
== AuthType.AWS_IAM
|
||||
)
|
||||
assert search(
|
||||
"lambda-url.eu-west-1.on.aws",
|
||||
awslambda.functions[lambda_name].url_config.url,
|
||||
)
|
||||
|
||||
assert awslambda.functions[lambda_name].url_config.cors_config
|
||||
assert awslambda.functions[
|
||||
lambda_name
|
||||
].url_config.cors_config.allow_origins == ["*"]
|
||||
|
||||
# Pending ZipFile tests
|
||||
with tempfile.TemporaryDirectory() as tmp_dir_name:
|
||||
awslambda.functions[lambda_name].code.code_zip.extractall(tmp_dir_name)
|
||||
files_in_zip = next(os.walk(tmp_dir_name))[2]
|
||||
assert len(files_in_zip) == 1
|
||||
assert files_in_zip[0] == "lambda_function.py"
|
||||
with open(f"{tmp_dir_name}/{files_in_zip[0]}", "r") as lambda_code_file:
|
||||
_ = lambda_code_file
|
||||
# assert (
|
||||
# lambda_code_file.read()
|
||||
# == """
|
||||
# def lambda_handler(event, context):
|
||||
# print("custom log event")
|
||||
# return event
|
||||
# """
|
||||
# )
|
||||
@@ -0,0 +1,133 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_service import Stack
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_cloudformation_outputs_find_secrets:
|
||||
def test_no_stacks(self):
|
||||
cloudformation_client = mock.MagicMock
|
||||
cloudformation_client.stacks = []
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudformation.cloudformation_service.CloudFormation",
|
||||
new=cloudformation_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_outputs_find_secrets.cloudformation_outputs_find_secrets import (
|
||||
cloudformation_outputs_find_secrets,
|
||||
)
|
||||
|
||||
check = cloudformation_outputs_find_secrets()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_stack_secret_in_outputs(self):
|
||||
cloudformation_client = mock.MagicMock
|
||||
stack_name = "Test-Stack"
|
||||
cloudformation_client.stacks = [
|
||||
Stack(
|
||||
arn="arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60",
|
||||
name=stack_name,
|
||||
outputs=["DB_PASSWORD:foobar123", "ENV:DEV"],
|
||||
region=AWS_REGION,
|
||||
)
|
||||
]
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudformation.cloudformation_service.CloudFormation",
|
||||
cloudformation_client,
|
||||
):
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_outputs_find_secrets.cloudformation_outputs_find_secrets import (
|
||||
cloudformation_outputs_find_secrets,
|
||||
)
|
||||
|
||||
check = cloudformation_outputs_find_secrets()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Potential secret found in Stack {stack_name} Outputs."
|
||||
)
|
||||
assert result[0].resource_id == "Test-Stack"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60"
|
||||
)
|
||||
assert result[0].region == AWS_REGION
|
||||
|
||||
def test_stack_no_secret_in_outputs(self):
|
||||
cloudformation_client = mock.MagicMock
|
||||
stack_name = "Test-Stack"
|
||||
cloudformation_client.stacks = [
|
||||
Stack(
|
||||
arn="arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60",
|
||||
name=stack_name,
|
||||
outputs=["ENV:DEV"],
|
||||
region=AWS_REGION,
|
||||
)
|
||||
]
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudformation.cloudformation_service.CloudFormation",
|
||||
cloudformation_client,
|
||||
):
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_outputs_find_secrets.cloudformation_outputs_find_secrets import (
|
||||
cloudformation_outputs_find_secrets,
|
||||
)
|
||||
|
||||
check = cloudformation_outputs_find_secrets()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"No secrets found in Stack {stack_name} Outputs."
|
||||
)
|
||||
assert result[0].resource_id == "Test-Stack"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60"
|
||||
)
|
||||
assert result[0].region == AWS_REGION
|
||||
|
||||
def test_stack_no_outputs(self):
|
||||
cloudformation_client = mock.MagicMock
|
||||
stack_name = "Test-Stack"
|
||||
cloudformation_client.stacks = [
|
||||
Stack(
|
||||
arn="arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60",
|
||||
name=stack_name,
|
||||
outputs=[],
|
||||
region=AWS_REGION,
|
||||
)
|
||||
]
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudformation.cloudformation_service.CloudFormation",
|
||||
cloudformation_client,
|
||||
):
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_outputs_find_secrets.cloudformation_outputs_find_secrets import (
|
||||
cloudformation_outputs_find_secrets,
|
||||
)
|
||||
|
||||
check = cloudformation_outputs_find_secrets()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFormation {stack_name} has no Outputs."
|
||||
)
|
||||
assert result[0].resource_id == "Test-Stack"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60"
|
||||
)
|
||||
assert result[0].region == AWS_REGION
|
||||
@@ -0,0 +1,210 @@
|
||||
import datetime
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
|
||||
import boto3
|
||||
import botocore
|
||||
from boto3 import session
|
||||
from dateutil.tz import tzutc
|
||||
from moto import mock_cloudformation
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_service import (
|
||||
CloudFormation,
|
||||
)
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
# Dummy CloudFormation Template
|
||||
dummy_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 1",
|
||||
"Resources": {
|
||||
"EC2Instance1": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
"Properties": {
|
||||
"ImageId": "EXAMPLE_AMI_ID",
|
||||
"KeyName": "dummy",
|
||||
"InstanceType": "t2.micro",
|
||||
"Tags": [
|
||||
{"Key": "Description", "Value": "Test tag"},
|
||||
{"Key": "Name", "Value": "Name tag for tests"},
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# Mocking Access Analyzer Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
"""
|
||||
As you can see the operation_name has the list_analyzers snake_case form but
|
||||
we are using the ListAnalyzers form.
|
||||
Rationale -> https://github.com/boto/botocore/blob/develop/botocore/client.py#L810:L816
|
||||
|
||||
We have to mock every AWS API call using Boto3
|
||||
"""
|
||||
if operation_name == "CreateStack":
|
||||
return {
|
||||
"StackId": "arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60"
|
||||
}
|
||||
if operation_name == "DescribeStacks":
|
||||
if "StackName" in kwarg:
|
||||
return {
|
||||
"Stacks": [
|
||||
{
|
||||
"StackId": "arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60",
|
||||
"StackName": "Test-Stack",
|
||||
"Description": "Stack 1",
|
||||
"Parameters": [],
|
||||
"CreationTime": datetime.datetime(
|
||||
2022, 11, 7, 9, 33, 51, tzinfo=tzutc()
|
||||
),
|
||||
"StackStatus": "CREATE_COMPLETE",
|
||||
"DisableRollback": False,
|
||||
"NotificationARNs": [],
|
||||
"Outputs": [
|
||||
{
|
||||
"OutputKey": "TestOutput1",
|
||||
"OutputValue": "TestValue1",
|
||||
"Description": "Test Output Description.",
|
||||
}
|
||||
],
|
||||
"RoleARN": "arn:aws:iam::123456789012:role/moto",
|
||||
"EnableTerminationProtection": True,
|
||||
"Tags": [
|
||||
{"Key": "Tag1", "Value": "Value1"},
|
||||
{"Key": "Tag2", "Value": "Value2"},
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
# Return all Stacks
|
||||
else:
|
||||
return {
|
||||
"Stacks": [
|
||||
{
|
||||
"StackId": "arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60",
|
||||
"StackName": "Test-Stack",
|
||||
"Description": "Stack 1",
|
||||
"Parameters": [],
|
||||
"CreationTime": datetime.datetime(
|
||||
2022, 11, 7, 9, 33, 51, tzinfo=tzutc()
|
||||
),
|
||||
"StackStatus": "CREATE_COMPLETE",
|
||||
"DisableRollback": False,
|
||||
"NotificationARNs": [],
|
||||
"Outputs": [
|
||||
{
|
||||
"OutputKey": "TestOutput1",
|
||||
"OutputValue": "TestValue1",
|
||||
"Description": "Test Output Description.",
|
||||
}
|
||||
],
|
||||
"RoleARN": "arn:aws:iam::123456789012:role/moto",
|
||||
"Tags": [
|
||||
{"Key": "Tag1", "Value": "Value1"},
|
||||
{"Key": "Tag2", "Value": "Value2"},
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
# Mock generate_regional_clients()
|
||||
def mock_generate_regional_clients(service, audit_info):
|
||||
regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION)
|
||||
regional_client.region = AWS_REGION
|
||||
return {AWS_REGION: regional_client}
|
||||
|
||||
|
||||
# Patch every AWS call using Boto3 and generate_regional_clients to have 1 client
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
@patch(
|
||||
"prowler.providers.aws.services.cloudformation.cloudformation_service.generate_regional_clients",
|
||||
new=mock_generate_regional_clients,
|
||||
)
|
||||
class Test_CloudFormation_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=None,
|
||||
audited_user_id=None,
|
||||
audited_partition=None,
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test CloudFormation Client
|
||||
@mock_cloudformation
|
||||
def test__get_client__(self):
|
||||
cloudformation = CloudFormation(self.set_mocked_audit_info())
|
||||
assert (
|
||||
cloudformation.regional_clients[AWS_REGION].__class__.__name__
|
||||
== "CloudFormation"
|
||||
)
|
||||
|
||||
# Test CloudFormation Service
|
||||
@mock_cloudformation
|
||||
def test__get_service__(self):
|
||||
cloudformation = CloudFormation(self.set_mocked_audit_info())
|
||||
assert (
|
||||
cloudformation.regional_clients[AWS_REGION].__class__.__name__
|
||||
== "CloudFormation"
|
||||
)
|
||||
|
||||
# Test CloudFormation Session
|
||||
@mock_cloudformation
|
||||
def test__get_session__(self):
|
||||
cloudformation = CloudFormation(self.set_mocked_audit_info())
|
||||
assert cloudformation.session.__class__.__name__ == "Session"
|
||||
|
||||
@mock_cloudformation
|
||||
def test__describe_stacks__(self):
|
||||
cloudformation_client = boto3.client("cloudformation", region_name=AWS_REGION)
|
||||
stack_arn = cloudformation_client.create_stack(
|
||||
StackName="Test-Stack",
|
||||
TemplateBody=json.dumps(dummy_template),
|
||||
RoleARN=f"arn:aws:iam::{DEFAULT_ACCOUNT_ID}:role/moto",
|
||||
Tags=[
|
||||
{"Key": "Tag1", "Value": "Value1"},
|
||||
{"Key": "Tag2", "Value": "Value2"},
|
||||
],
|
||||
EnableTerminationProtection=True,
|
||||
Outputs=[
|
||||
{
|
||||
"OutputKey": "TestOutput1",
|
||||
"OutputValue": "TestValue1",
|
||||
"Description": "Test Output Description.",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
cloudformation = CloudFormation(self.set_mocked_audit_info())
|
||||
assert len(cloudformation.stacks) == 1
|
||||
assert cloudformation.stacks[0].arn == stack_arn["StackId"]
|
||||
assert cloudformation.stacks[0].name == "Test-Stack"
|
||||
assert cloudformation.stacks[0].outputs == ["TestOutput1:TestValue1"]
|
||||
assert cloudformation.stacks[0].enable_termination_protection is True
|
||||
assert cloudformation.stacks[0].is_nested_stack is False
|
||||
assert cloudformation.stacks[0].root_nested_stack == ""
|
||||
assert cloudformation.stacks[0].region == AWS_REGION
|
||||
@@ -0,0 +1,99 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_service import Stack
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_cloudformation_stacks_termination_protection_enabled:
|
||||
def test_no_stacks(self):
|
||||
cloudformation_client = mock.MagicMock
|
||||
cloudformation_client.stacks = []
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudformation.cloudformation_service.CloudFormation",
|
||||
new=cloudformation_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_stacks_termination_protection_enabled.cloudformation_stacks_termination_protection_enabled import (
|
||||
cloudformation_stacks_termination_protection_enabled,
|
||||
)
|
||||
|
||||
check = cloudformation_stacks_termination_protection_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_stack_termination_protection_enabled(self):
|
||||
cloudformation_client = mock.MagicMock
|
||||
stack_name = "Test-Stack"
|
||||
cloudformation_client.stacks = [
|
||||
Stack(
|
||||
arn="arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60",
|
||||
name=stack_name,
|
||||
outputs="",
|
||||
region=AWS_REGION,
|
||||
)
|
||||
]
|
||||
cloudformation_client.stacks[0].enable_termination_protection = True
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudformation.cloudformation_service.CloudFormation",
|
||||
cloudformation_client,
|
||||
):
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_stacks_termination_protection_enabled.cloudformation_stacks_termination_protection_enabled import (
|
||||
cloudformation_stacks_termination_protection_enabled,
|
||||
)
|
||||
|
||||
check = cloudformation_stacks_termination_protection_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFormation {stack_name} has termination protection enabled"
|
||||
)
|
||||
assert result[0].resource_id == "Test-Stack"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60"
|
||||
)
|
||||
assert result[0].region == AWS_REGION
|
||||
|
||||
def test_stack_termination_protection_disabled(self):
|
||||
cloudformation_client = mock.MagicMock
|
||||
stack_name = "Test-Stack"
|
||||
cloudformation_client.stacks = [
|
||||
Stack(
|
||||
arn="arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60",
|
||||
name=stack_name,
|
||||
outputs="",
|
||||
region=AWS_REGION,
|
||||
)
|
||||
]
|
||||
cloudformation_client.stacks[0].enable_termination_protection = False
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudformation.cloudformation_service.CloudFormation",
|
||||
cloudformation_client,
|
||||
):
|
||||
from prowler.providers.aws.services.cloudformation.cloudformation_stacks_termination_protection_enabled.cloudformation_stacks_termination_protection_enabled import (
|
||||
cloudformation_stacks_termination_protection_enabled,
|
||||
)
|
||||
|
||||
check = cloudformation_stacks_termination_protection_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFormation {stack_name} has termination protection disabled"
|
||||
)
|
||||
assert result[0].resource_id == "Test-Stack"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:cloudformation:eu-west-1:123456789012:stack/Test-Stack/796c8d26-b390-41d7-a23c-0702c4e78b60"
|
||||
)
|
||||
assert result[0].region == AWS_REGION
|
||||
@@ -0,0 +1,110 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_service import (
|
||||
DefaultCacheConfigBehaviour,
|
||||
Distribution,
|
||||
ViewerProtocolPolicy,
|
||||
)
|
||||
|
||||
DISTRIBUTION_ID = "E27LVI50CSW06W"
|
||||
DISTRIBUTION_ARN = (
|
||||
f"arn:aws:cloudfront::{DEFAULT_ACCOUNT_ID}:distribution/{DISTRIBUTION_ID}"
|
||||
)
|
||||
REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_cloudfront_distributions_field_level_encryption_enabled:
|
||||
def test_no_distributions(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_field_level_encryption_enabled.cloudfront_distributions_field_level_encryption_enabled import (
|
||||
cloudfront_distributions_field_level_encryption_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_field_level_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_distribution_field_level_encryption_enabled(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[],
|
||||
default_cache_config=DefaultCacheConfigBehaviour(
|
||||
realtime_log_config_arn="",
|
||||
viewer_protocol_policy=ViewerProtocolPolicy.https_only,
|
||||
field_level_encryption_id="AAAAAAAA",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_field_level_encryption_enabled.cloudfront_distributions_field_level_encryption_enabled import (
|
||||
cloudfront_distributions_field_level_encryption_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_field_level_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has Field Level Encryption enabled"
|
||||
)
|
||||
|
||||
def test_one_distribution_field_level_encryption_disabled(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[],
|
||||
default_cache_config=DefaultCacheConfigBehaviour(
|
||||
realtime_log_config_arn="",
|
||||
viewer_protocol_policy=ViewerProtocolPolicy.https_only,
|
||||
field_level_encryption_id="",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_field_level_encryption_enabled.cloudfront_distributions_field_level_encryption_enabled import (
|
||||
cloudfront_distributions_field_level_encryption_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_field_level_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has Field Level Encryption disabled"
|
||||
)
|
||||
@@ -0,0 +1,135 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_service import (
|
||||
Distribution,
|
||||
GeoRestrictionType,
|
||||
)
|
||||
|
||||
DISTRIBUTION_ID = "E27LVI50CSW06W"
|
||||
DISTRIBUTION_ARN = (
|
||||
f"arn:aws:cloudfront::{DEFAULT_ACCOUNT_ID}:distribution/{DISTRIBUTION_ID}"
|
||||
)
|
||||
REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_cloudfront_distributions_geo_restrictions_enabled:
|
||||
def test_no_distributions(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_geo_restrictions_enabled.cloudfront_distributions_geo_restrictions_enabled import (
|
||||
cloudfront_distributions_geo_restrictions_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_geo_restrictions_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_distribution_geo_restriction_disabled(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[],
|
||||
geo_restriction_type=GeoRestrictionType.none,
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_geo_restrictions_enabled.cloudfront_distributions_geo_restrictions_enabled import (
|
||||
cloudfront_distributions_geo_restrictions_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_geo_restrictions_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has Geo restrictions disabled"
|
||||
)
|
||||
|
||||
def test_one_distribution_geo_restriction_enabled_whitelist(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[],
|
||||
geo_restriction_type=GeoRestrictionType.whitelist,
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_geo_restrictions_enabled.cloudfront_distributions_geo_restrictions_enabled import (
|
||||
cloudfront_distributions_geo_restrictions_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_geo_restrictions_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has Geo restrictions enabled"
|
||||
)
|
||||
|
||||
def test_one_distribution_geo_restriction_enabled_blacklist(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[],
|
||||
geo_restriction_type=GeoRestrictionType.blacklist,
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_geo_restrictions_enabled.cloudfront_distributions_geo_restrictions_enabled import (
|
||||
cloudfront_distributions_geo_restrictions_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_geo_restrictions_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has Geo restrictions enabled"
|
||||
)
|
||||
@@ -0,0 +1,148 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_service import (
|
||||
DefaultCacheConfigBehaviour,
|
||||
Distribution,
|
||||
ViewerProtocolPolicy,
|
||||
)
|
||||
|
||||
DISTRIBUTION_ID = "E27LVI50CSW06W"
|
||||
DISTRIBUTION_ARN = (
|
||||
f"arn:aws:cloudfront::{DEFAULT_ACCOUNT_ID}:distribution/{DISTRIBUTION_ID}"
|
||||
)
|
||||
REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_cloudfront_distributions_https_enabled:
|
||||
def test_no_distributions(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_https_enabled.cloudfront_distributions_https_enabled import (
|
||||
cloudfront_distributions_https_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_https_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_distribution_https_disabled(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[],
|
||||
default_cache_config=DefaultCacheConfigBehaviour(
|
||||
realtime_log_config_arn="",
|
||||
viewer_protocol_policy=ViewerProtocolPolicy.allow_all,
|
||||
field_level_encryption_id="",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_https_enabled.cloudfront_distributions_https_enabled import (
|
||||
cloudfront_distributions_https_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_https_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} viewers can use HTTP or HTTPS"
|
||||
)
|
||||
|
||||
def test_one_distribution_https_redirect(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[],
|
||||
default_cache_config=DefaultCacheConfigBehaviour(
|
||||
realtime_log_config_arn="",
|
||||
viewer_protocol_policy=ViewerProtocolPolicy.redirect_to_https,
|
||||
field_level_encryption_id="",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_https_enabled.cloudfront_distributions_https_enabled import (
|
||||
cloudfront_distributions_https_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_https_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has redirect to HTTPS"
|
||||
)
|
||||
|
||||
def test_one_distribution_https_only(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[],
|
||||
default_cache_config=DefaultCacheConfigBehaviour(
|
||||
realtime_log_config_arn="",
|
||||
viewer_protocol_policy=ViewerProtocolPolicy.https_only,
|
||||
field_level_encryption_id="",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_https_enabled.cloudfront_distributions_https_enabled import (
|
||||
cloudfront_distributions_https_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_https_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has HTTPS only"
|
||||
)
|
||||
@@ -0,0 +1,185 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_service import (
|
||||
DefaultCacheConfigBehaviour,
|
||||
Distribution,
|
||||
ViewerProtocolPolicy,
|
||||
)
|
||||
|
||||
DISTRIBUTION_ID = "E27LVI50CSW06W"
|
||||
DISTRIBUTION_ARN = (
|
||||
f"arn:aws:cloudfront::{DEFAULT_ACCOUNT_ID}:distribution/{DISTRIBUTION_ID}"
|
||||
)
|
||||
REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_cloudfront_distributions_logging_enabled:
|
||||
def test_no_distributions(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_logging_enabled.cloudfront_distributions_logging_enabled import (
|
||||
cloudfront_distributions_logging_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_distribution_logging_enabled(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
logging_enabled=True,
|
||||
origins=[],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_logging_enabled.cloudfront_distributions_logging_enabled import (
|
||||
cloudfront_distributions_logging_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has logging enabled"
|
||||
)
|
||||
|
||||
def test_one_distribution_logging_disabled_realtime_disabled(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
logging_enabled=False,
|
||||
default_cache_config=DefaultCacheConfigBehaviour(
|
||||
realtime_log_config_arn="",
|
||||
viewer_protocol_policy=ViewerProtocolPolicy.https_only,
|
||||
field_level_encryption_id="",
|
||||
),
|
||||
origins=[],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_logging_enabled.cloudfront_distributions_logging_enabled import (
|
||||
cloudfront_distributions_logging_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has logging disabled"
|
||||
)
|
||||
|
||||
def test_one_distribution_logging_disabled_realtime_enabled(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
logging_enabled=False,
|
||||
default_cache_config=DefaultCacheConfigBehaviour(
|
||||
realtime_log_config_arn=DISTRIBUTION_ARN,
|
||||
viewer_protocol_policy=ViewerProtocolPolicy.https_only,
|
||||
field_level_encryption_id="",
|
||||
),
|
||||
origins=[],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_logging_enabled.cloudfront_distributions_logging_enabled import (
|
||||
cloudfront_distributions_logging_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has logging enabled"
|
||||
)
|
||||
|
||||
def test_one_distribution_logging_enabled_realtime_enabled(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
logging_enabled=True,
|
||||
default_cache_config=DefaultCacheConfigBehaviour(
|
||||
realtime_log_config_arn=DISTRIBUTION_ARN,
|
||||
viewer_protocol_policy=ViewerProtocolPolicy.https_only,
|
||||
field_level_encryption_id="",
|
||||
),
|
||||
origins=[],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_logging_enabled.cloudfront_distributions_logging_enabled import (
|
||||
cloudfront_distributions_logging_enabled,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} has logging enabled"
|
||||
)
|
||||
@@ -0,0 +1,306 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_service import Distribution
|
||||
|
||||
DISTRIBUTION_ID = "E27LVI50CSW06W"
|
||||
DISTRIBUTION_ARN = (
|
||||
f"arn:aws:cloudfront::{DEFAULT_ACCOUNT_ID}:distribution/{DISTRIBUTION_ID}"
|
||||
)
|
||||
REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_cloudfront_distributions_using_deprecated_ssl_protocols:
|
||||
def test_no_distributions(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_using_deprecated_ssl_protocols.cloudfront_distributions_using_deprecated_ssl_protocols import (
|
||||
cloudfront_distributions_using_deprecated_ssl_protocols,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_using_deprecated_ssl_protocols()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_distribution_using_deprecated_ssl_protocols(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[
|
||||
{
|
||||
"Id": "string",
|
||||
"DomainName": "string",
|
||||
"OriginPath": "string",
|
||||
"CustomHeaders": {
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
{
|
||||
"HeaderName": "string",
|
||||
"HeaderValue": "string",
|
||||
},
|
||||
],
|
||||
},
|
||||
"S3OriginConfig": {"OriginAccessIdentity": "string"},
|
||||
"CustomOriginConfig": {
|
||||
"HTTPPort": 123,
|
||||
"HTTPSPort": 123,
|
||||
"OriginProtocolPolicy": "https-only",
|
||||
"OriginSslProtocols": {
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
"SSLv3",
|
||||
],
|
||||
},
|
||||
"OriginReadTimeout": 123,
|
||||
"OriginKeepaliveTimeout": 123,
|
||||
},
|
||||
"ConnectionAttempts": 123,
|
||||
"ConnectionTimeout": 123,
|
||||
"OriginShield": {
|
||||
"Enabled": False,
|
||||
"OriginShieldRegion": "string",
|
||||
},
|
||||
"OriginAccessControlId": "string",
|
||||
},
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_using_deprecated_ssl_protocols.cloudfront_distributions_using_deprecated_ssl_protocols import (
|
||||
cloudfront_distributions_using_deprecated_ssl_protocols,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_using_deprecated_ssl_protocols()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} is using a deprecated SSL protocol"
|
||||
)
|
||||
|
||||
def test_one_distribution_using_SSL_and_TLS(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[
|
||||
{
|
||||
"Id": "string",
|
||||
"DomainName": "string",
|
||||
"OriginPath": "string",
|
||||
"CustomHeaders": {
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
{
|
||||
"HeaderName": "string",
|
||||
"HeaderValue": "string",
|
||||
},
|
||||
],
|
||||
},
|
||||
"S3OriginConfig": {"OriginAccessIdentity": "string"},
|
||||
"CustomOriginConfig": {
|
||||
"HTTPPort": 123,
|
||||
"HTTPSPort": 123,
|
||||
"OriginProtocolPolicy": "https-only",
|
||||
"OriginSslProtocols": {
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
"SSLv3",
|
||||
"TLSv1.2",
|
||||
],
|
||||
},
|
||||
"OriginReadTimeout": 123,
|
||||
"OriginKeepaliveTimeout": 123,
|
||||
},
|
||||
"ConnectionAttempts": 123,
|
||||
"ConnectionTimeout": 123,
|
||||
"OriginShield": {
|
||||
"Enabled": False,
|
||||
"OriginShieldRegion": "string",
|
||||
},
|
||||
"OriginAccessControlId": "string",
|
||||
},
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_using_deprecated_ssl_protocols.cloudfront_distributions_using_deprecated_ssl_protocols import (
|
||||
cloudfront_distributions_using_deprecated_ssl_protocols,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_using_deprecated_ssl_protocols()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} is using a deprecated SSL protocol"
|
||||
)
|
||||
|
||||
def test_one_distribution_using_SSL_and_bad_TLS(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[
|
||||
{
|
||||
"Id": "string",
|
||||
"DomainName": "string",
|
||||
"OriginPath": "string",
|
||||
"CustomHeaders": {
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
{
|
||||
"HeaderName": "string",
|
||||
"HeaderValue": "string",
|
||||
},
|
||||
],
|
||||
},
|
||||
"S3OriginConfig": {"OriginAccessIdentity": "string"},
|
||||
"CustomOriginConfig": {
|
||||
"HTTPPort": 123,
|
||||
"HTTPSPort": 123,
|
||||
"OriginProtocolPolicy": "https-only",
|
||||
"OriginSslProtocols": {
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
"SSLv3",
|
||||
"TLSv1.1",
|
||||
],
|
||||
},
|
||||
"OriginReadTimeout": 123,
|
||||
"OriginKeepaliveTimeout": 123,
|
||||
},
|
||||
"ConnectionAttempts": 123,
|
||||
"ConnectionTimeout": 123,
|
||||
"OriginShield": {
|
||||
"Enabled": False,
|
||||
"OriginShieldRegion": "string",
|
||||
},
|
||||
"OriginAccessControlId": "string",
|
||||
},
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_using_deprecated_ssl_protocols.cloudfront_distributions_using_deprecated_ssl_protocols import (
|
||||
cloudfront_distributions_using_deprecated_ssl_protocols,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_using_deprecated_ssl_protocols()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} is using a deprecated SSL protocol"
|
||||
)
|
||||
|
||||
def test_one_distribution_not_using_deprecated_ssl_protocols(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[
|
||||
{
|
||||
"Id": "string",
|
||||
"DomainName": "string",
|
||||
"OriginPath": "string",
|
||||
"CustomHeaders": {
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
{
|
||||
"HeaderName": "string",
|
||||
"HeaderValue": "string",
|
||||
},
|
||||
],
|
||||
},
|
||||
"S3OriginConfig": {"OriginAccessIdentity": "string"},
|
||||
"CustomOriginConfig": {
|
||||
"HTTPPort": 123,
|
||||
"HTTPSPort": 123,
|
||||
"OriginProtocolPolicy": "https-only",
|
||||
"OriginSslProtocols": {
|
||||
"Quantity": 123,
|
||||
"Items": ["TLSv1.2"],
|
||||
},
|
||||
"OriginReadTimeout": 123,
|
||||
"OriginKeepaliveTimeout": 123,
|
||||
},
|
||||
"ConnectionAttempts": 123,
|
||||
"ConnectionTimeout": 123,
|
||||
"OriginShield": {
|
||||
"Enabled": False,
|
||||
"OriginShieldRegion": "string",
|
||||
},
|
||||
"OriginAccessControlId": "string",
|
||||
},
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_using_deprecated_ssl_protocols.cloudfront_distributions_using_deprecated_ssl_protocols import (
|
||||
cloudfront_distributions_using_deprecated_ssl_protocols,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_using_deprecated_ssl_protocols()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} is not using a deprecated SSL protocol"
|
||||
)
|
||||
@@ -0,0 +1,98 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_service import Distribution
|
||||
|
||||
DISTRIBUTION_ID = "E27LVI50CSW06W"
|
||||
DISTRIBUTION_ARN = (
|
||||
f"arn:aws:cloudfront::{DEFAULT_ACCOUNT_ID}:distribution/{DISTRIBUTION_ID}"
|
||||
)
|
||||
REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_cloudfront_distributions_using_waf:
|
||||
def test_no_distributions(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_using_waf.cloudfront_distributions_using_waf import (
|
||||
cloudfront_distributions_using_waf,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_using_waf()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_distribution_waf(self):
|
||||
wef_acl_id = "TEST-WAF-ACL"
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
web_acl_id=wef_acl_id,
|
||||
origins=[],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_using_waf.cloudfront_distributions_using_waf import (
|
||||
cloudfront_distributions_using_waf,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_using_waf()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} is using AWS WAF web ACL {wef_acl_id}"
|
||||
)
|
||||
|
||||
def test_one_distribution_no_waf(self):
|
||||
cloudfront_client = mock.MagicMock
|
||||
cloudfront_client.distributions = {
|
||||
"DISTRIBUTION_ID": Distribution(
|
||||
arn=DISTRIBUTION_ARN,
|
||||
id=DISTRIBUTION_ID,
|
||||
region=REGION,
|
||||
origins=[],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudfront.cloudfront_service.CloudFront",
|
||||
new=cloudfront_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_distributions_using_waf.cloudfront_distributions_using_waf import (
|
||||
cloudfront_distributions_using_waf,
|
||||
)
|
||||
|
||||
check = cloudfront_distributions_using_waf()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == REGION
|
||||
assert result[0].resource_arn == DISTRIBUTION_ARN
|
||||
assert result[0].resource_id == DISTRIBUTION_ID
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"CloudFront Distribution {DISTRIBUTION_ID} is not using AWS WAF web ACL"
|
||||
)
|
||||
@@ -0,0 +1,247 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
import botocore
|
||||
from boto3 import client, session
|
||||
from moto import mock_cloudfront
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.cloudfront.cloudfront_service import CloudFront
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
def example_distribution_config(ref):
|
||||
"""Return a basic example distribution config for use in tests."""
|
||||
return {
|
||||
"CallerReference": ref,
|
||||
"Origins": {
|
||||
"Quantity": 1,
|
||||
"Items": [
|
||||
{
|
||||
"Id": "origin1",
|
||||
"DomainName": "asdf.s3.us-east-1.amazonaws.com",
|
||||
"S3OriginConfig": {"OriginAccessIdentity": ""},
|
||||
}
|
||||
],
|
||||
},
|
||||
"DefaultCacheBehavior": {
|
||||
"TargetOriginId": "origin1",
|
||||
"ViewerProtocolPolicy": "allow-all",
|
||||
"MinTTL": 10,
|
||||
"ForwardedValues": {
|
||||
"QueryString": False,
|
||||
"Cookies": {"Forward": "none"},
|
||||
},
|
||||
},
|
||||
"Comment": "an optional comment that's not actually optional",
|
||||
"Enabled": False,
|
||||
}
|
||||
|
||||
|
||||
# Mocking Access Analyzer Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
"""
|
||||
As you can see the operation_name has the list_analyzers snake_case form but
|
||||
we are using the ListAnalyzers form.
|
||||
Rationale -> https://github.com/boto/botocore/blob/develop/botocore/client.py#L810:L816
|
||||
|
||||
We have to mock every AWS API call using Boto3
|
||||
"""
|
||||
if operation_name == "GetDistributionConfig":
|
||||
if kwarg["Id"]:
|
||||
return {
|
||||
"DistributionConfig": {
|
||||
"Origins": {"Quantity": 123, "Items": []},
|
||||
"OriginGroups": {"Quantity": 123, "Items": []},
|
||||
"DefaultCacheBehavior": {
|
||||
"TargetOriginId": "",
|
||||
"TrustedSigners": {
|
||||
"Enabled": False,
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
"",
|
||||
],
|
||||
},
|
||||
"TrustedKeyGroups": {
|
||||
"Enabled": False,
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
"",
|
||||
],
|
||||
},
|
||||
"ViewerProtocolPolicy": "https-only",
|
||||
"AllowedMethods": {
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
"GET",
|
||||
],
|
||||
"CachedMethods": {
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
"GET",
|
||||
],
|
||||
},
|
||||
},
|
||||
"SmoothStreaming": False,
|
||||
"Compress": False,
|
||||
"LambdaFunctionAssociations": {},
|
||||
"FunctionAssociations": {},
|
||||
"FieldLevelEncryptionId": "enabled",
|
||||
"RealtimeLogConfigArn": "test-log-arn",
|
||||
"CachePolicyId": "",
|
||||
"OriginRequestPolicyId": "",
|
||||
"ResponseHeadersPolicyId": "",
|
||||
"ForwardedValues": {
|
||||
"QueryString": False,
|
||||
"Cookies": {},
|
||||
"Headers": {},
|
||||
"QueryStringCacheKeys": {},
|
||||
},
|
||||
"MinTTL": 123,
|
||||
"DefaultTTL": 123,
|
||||
"MaxTTL": 123,
|
||||
},
|
||||
"CacheBehaviors": {},
|
||||
"CustomErrorResponses": {},
|
||||
"Comment": "",
|
||||
"Logging": {
|
||||
"Enabled": True,
|
||||
"IncludeCookies": False,
|
||||
"Bucket": "",
|
||||
"Prefix": "",
|
||||
},
|
||||
"PriceClass": "PriceClass_All",
|
||||
"Enabled": False,
|
||||
"ViewerCertificate": {},
|
||||
"Restrictions": {
|
||||
"GeoRestriction": {
|
||||
"RestrictionType": "blacklist",
|
||||
"Quantity": 123,
|
||||
"Items": [
|
||||
"",
|
||||
],
|
||||
}
|
||||
},
|
||||
"WebACLId": "test-web-acl",
|
||||
"HttpVersion": "http2and3",
|
||||
"IsIPV6Enabled": False,
|
||||
},
|
||||
"ETag": "",
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
# PENDING PR TO GET THE PARAMETERS USING MOTO
|
||||
|
||||
|
||||
# Patch every AWS call using Boto3
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
class Test_CloudFront_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
region_name=AWS_REGION,
|
||||
),
|
||||
audited_account=DEFAULT_ACCOUNT_ID,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=AWS_REGION,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test CloudFront Client
|
||||
@mock_cloudfront
|
||||
def test__get_client__(self):
|
||||
cloudfront = CloudFront(self.set_mocked_audit_info())
|
||||
assert cloudfront.client.__class__.__name__ == "CloudFront"
|
||||
|
||||
# Test CloudFront Session
|
||||
@mock_cloudfront
|
||||
def test__get_session__(self):
|
||||
cloudfront = CloudFront(self.set_mocked_audit_info())
|
||||
assert cloudfront.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test CloudFront Service
|
||||
@mock_cloudfront
|
||||
def test__get_service__(self):
|
||||
cloudfront = CloudFront(self.set_mocked_audit_info())
|
||||
assert cloudfront.service == "cloudfront"
|
||||
|
||||
@mock_cloudfront
|
||||
def test__list_distributions__zero(self):
|
||||
cloudfront = CloudFront(self.set_mocked_audit_info())
|
||||
|
||||
assert len(cloudfront.distributions) == 0
|
||||
|
||||
@mock_cloudfront
|
||||
def test__list_distributions__complete(self):
|
||||
cloudfront_client = client("cloudfront")
|
||||
config = example_distribution_config("ref")
|
||||
response = cloudfront_client.create_distribution(DistributionConfig=config)
|
||||
cloudfront_distribution_id = response["Distribution"]["Id"]
|
||||
cloudfront_distribution_arn = response["Distribution"]["ARN"]
|
||||
cloudfront = CloudFront(self.set_mocked_audit_info())
|
||||
|
||||
assert len(cloudfront.distributions) == 1
|
||||
assert (
|
||||
cloudfront.distributions[cloudfront_distribution_id].arn
|
||||
== cloudfront_distribution_arn
|
||||
)
|
||||
assert (
|
||||
cloudfront.distributions[cloudfront_distribution_id].id
|
||||
== cloudfront_distribution_id
|
||||
)
|
||||
assert (
|
||||
cloudfront.distributions[cloudfront_distribution_id].region
|
||||
== self.set_mocked_audit_info().audit_session.region_name
|
||||
)
|
||||
assert (
|
||||
cloudfront.distributions[cloudfront_distribution_id].logging_enabled is True
|
||||
)
|
||||
assert (
|
||||
cloudfront.distributions[cloudfront_distribution_id].origins
|
||||
== cloudfront_client.get_distribution(Id=cloudfront_distribution_id)[
|
||||
"Distribution"
|
||||
]["DistributionConfig"]["Origins"]["Items"]
|
||||
)
|
||||
assert (
|
||||
cloudfront.distributions[cloudfront_distribution_id].geo_restriction_type
|
||||
== "blacklist"
|
||||
)
|
||||
assert (
|
||||
cloudfront.distributions[cloudfront_distribution_id].web_acl_id
|
||||
== "test-web-acl"
|
||||
)
|
||||
assert (
|
||||
cloudfront.distributions[
|
||||
cloudfront_distribution_id
|
||||
].default_cache_config.realtime_log_config_arn
|
||||
== "test-log-arn"
|
||||
)
|
||||
assert (
|
||||
cloudfront.distributions[
|
||||
cloudfront_distribution_id
|
||||
].default_cache_config.viewer_protocol_policy
|
||||
== "https-only"
|
||||
)
|
||||
assert (
|
||||
cloudfront.distributions[
|
||||
cloudfront_distribution_id
|
||||
].default_cache_config.field_level_encryption_id
|
||||
== "enabled"
|
||||
)
|
||||
@@ -0,0 +1,231 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
|
||||
|
||||
class Test_cloudtrail_cloudwatch_logging_enabled:
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trails_sending_logs_during_and_not_last_day(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
cloudtrail_client_eu_west_1 = client("cloudtrail", region_name="eu-west-1")
|
||||
s3_client_eu_west_1 = client("s3", region_name="eu-west-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
trail_name_eu = "trail_test_eu"
|
||||
bucket_name_eu = "bucket_test_eu"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
s3_client_eu_west_1.create_bucket(
|
||||
Bucket=bucket_name_eu,
|
||||
CreateBucketConfiguration={"LocationConstraint": "eu-west-1"},
|
||||
)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
trail_eu = cloudtrail_client_eu_west_1.create_trail(
|
||||
Name=trail_name_eu, S3BucketName=bucket_name_eu, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_cloudwatch_logging_enabled.cloudtrail_cloudwatch_logging_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_cloudwatch_logging_enabled.cloudtrail_cloudwatch_logging_enabled import (
|
||||
cloudtrail_cloudwatch_logging_enabled,
|
||||
)
|
||||
|
||||
for trail in service_client.trails:
|
||||
if trail.name == trail_name_us:
|
||||
trail.latest_cloudwatch_delivery_time = datetime.now().replace(
|
||||
tzinfo=timezone.utc
|
||||
)
|
||||
elif trail.name == trail_name_eu:
|
||||
trail.latest_cloudwatch_delivery_time = (
|
||||
datetime.now() - timedelta(days=2)
|
||||
).replace(tzinfo=timezone.utc)
|
||||
|
||||
regions = []
|
||||
for region in service_client.regional_clients.keys():
|
||||
regions.append(region)
|
||||
|
||||
check = cloudtrail_cloudwatch_logging_enabled()
|
||||
result = check.execute()
|
||||
# len of result if has to be 2 since we only have 2 single region trails
|
||||
assert len(result) == 2
|
||||
for report in result:
|
||||
if report.resource_id == trail_name_us:
|
||||
assert report.resource_id == trail_name_us
|
||||
assert report.resource_arn == trail_us["TrailARN"]
|
||||
assert report.status == "PASS"
|
||||
assert search(
|
||||
report.status_extended,
|
||||
f"Single region trail {trail_name_us} has been logging the last 24h",
|
||||
)
|
||||
if report.resource_id == trail_name_eu:
|
||||
assert report.resource_id == trail_name_eu
|
||||
assert report.resource_arn == trail_eu["TrailARN"]
|
||||
assert report.status == "FAIL"
|
||||
assert search(
|
||||
report.status_extended,
|
||||
f"Single region trail {trail_name_eu} is not logging in the last 24h",
|
||||
)
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_multi_region_and_single_region_logging_and_not(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
cloudtrail_client_eu_west_1 = client("cloudtrail", region_name="eu-west-1")
|
||||
s3_client_eu_west_1 = client("s3", region_name="eu-west-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
trail_name_eu = "trail_test_eu"
|
||||
bucket_name_eu = "bucket_test_eu"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
s3_client_eu_west_1.create_bucket(
|
||||
Bucket=bucket_name_eu,
|
||||
CreateBucketConfiguration={"LocationConstraint": "eu-west-1"},
|
||||
)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=True
|
||||
)
|
||||
trail_eu = cloudtrail_client_eu_west_1.create_trail(
|
||||
Name=trail_name_eu, S3BucketName=bucket_name_eu, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_cloudwatch_logging_enabled.cloudtrail_cloudwatch_logging_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_cloudwatch_logging_enabled.cloudtrail_cloudwatch_logging_enabled import (
|
||||
cloudtrail_cloudwatch_logging_enabled,
|
||||
)
|
||||
|
||||
for trail in service_client.trails:
|
||||
if trail.name == trail_name_us:
|
||||
trail.latest_cloudwatch_delivery_time = datetime.now().replace(
|
||||
tzinfo=timezone.utc
|
||||
)
|
||||
elif trail.name == trail_name_eu:
|
||||
trail.latest_cloudwatch_delivery_time = (
|
||||
datetime.now() - timedelta(days=2)
|
||||
).replace(tzinfo=timezone.utc)
|
||||
|
||||
regions = []
|
||||
for region in service_client.regional_clients.keys():
|
||||
regions.append(region)
|
||||
|
||||
check = cloudtrail_cloudwatch_logging_enabled()
|
||||
result = check.execute()
|
||||
# len of result should be 24 -> (1 multiregion entry per region + 1 entry because of single region trail)
|
||||
assert len(result) == 26
|
||||
for report in result:
|
||||
if report.resource_id == trail_name_us:
|
||||
assert report.resource_id == trail_name_us
|
||||
assert report.resource_arn == trail_us["TrailARN"]
|
||||
assert report.status == "PASS"
|
||||
assert search(
|
||||
report.status_extended,
|
||||
f"Multiregion trail {trail_name_us} has been logging the last 24h",
|
||||
)
|
||||
if report.resource_id == trail_name_eu and report.region == "eu-west-1":
|
||||
assert report.resource_id == trail_name_eu
|
||||
assert report.resource_arn == trail_eu["TrailARN"]
|
||||
assert report.status == "FAIL"
|
||||
assert search(
|
||||
report.status_extended,
|
||||
f"Single region trail {trail_name_eu} is not logging in the last 24h",
|
||||
)
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trails_sending_and_not_sending_logs(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
cloudtrail_client_eu_west_1 = client("cloudtrail", region_name="eu-west-1")
|
||||
s3_client_eu_west_1 = client("s3", region_name="eu-west-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
trail_name_eu = "trail_test_eu"
|
||||
bucket_name_eu = "bucket_test_eu"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
s3_client_eu_west_1.create_bucket(
|
||||
Bucket=bucket_name_eu,
|
||||
CreateBucketConfiguration={"LocationConstraint": "eu-west-1"},
|
||||
)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
trail_eu = cloudtrail_client_eu_west_1.create_trail(
|
||||
Name=trail_name_eu, S3BucketName=bucket_name_eu, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_cloudwatch_logging_enabled.cloudtrail_cloudwatch_logging_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_cloudwatch_logging_enabled.cloudtrail_cloudwatch_logging_enabled import (
|
||||
cloudtrail_cloudwatch_logging_enabled,
|
||||
)
|
||||
|
||||
for trail in service_client.trails:
|
||||
if trail.name == trail_name_us:
|
||||
trail.latest_cloudwatch_delivery_time = datetime.now().replace(
|
||||
tzinfo=timezone.utc
|
||||
)
|
||||
elif trail.name == trail_name_us:
|
||||
trail.latest_cloudwatch_delivery_time = None
|
||||
|
||||
regions = []
|
||||
for region in service_client.regional_clients.keys():
|
||||
regions.append(region)
|
||||
|
||||
check = cloudtrail_cloudwatch_logging_enabled()
|
||||
result = check.execute()
|
||||
# len of result if has to be 2 since we only have 2 single region trails
|
||||
assert len(result) == 2
|
||||
for report in result:
|
||||
if report.resource_id == trail_name_us:
|
||||
assert report.resource_id == trail_name_us
|
||||
assert report.resource_arn == trail_us["TrailARN"]
|
||||
assert report.status == "PASS"
|
||||
assert search(
|
||||
report.status_extended,
|
||||
f"Single region trail {trail_name_us} has been logging the last 24h",
|
||||
)
|
||||
if report.resource_id == trail_name_eu:
|
||||
assert report.resource_id == trail_name_eu
|
||||
assert report.resource_arn == trail_eu["TrailARN"]
|
||||
assert report.status == "FAIL"
|
||||
assert search(
|
||||
report.status_extended,
|
||||
f"Single region trail {trail_name_eu} is not configured to deliver logs",
|
||||
)
|
||||
@@ -0,0 +1,93 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_kms, mock_s3
|
||||
|
||||
|
||||
class Test_cloudtrail_kms_encryption_enabled:
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_no_kms(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_kms_encryption_enabled.cloudtrail_kms_encryption_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_kms_encryption_enabled.cloudtrail_kms_encryption_enabled import (
|
||||
cloudtrail_kms_encryption_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_kms_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"has encryption disabled",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
@mock_kms
|
||||
def test_trail_kms(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
kms_client = client("kms", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
key_arn = kms_client.create_key()["KeyMetadata"]["Arn"]
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us,
|
||||
S3BucketName=bucket_name_us,
|
||||
IsMultiRegionTrail=False,
|
||||
KmsKeyId=key_arn,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_kms_encryption_enabled.cloudtrail_kms_encryption_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_kms_encryption_enabled.cloudtrail_kms_encryption_enabled import (
|
||||
cloudtrail_kms_encryption_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_kms_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"has encryption enabled",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
@@ -0,0 +1,106 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
|
||||
|
||||
class Test_cloudtrail_log_file_validation_enabled:
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_no_logging_validation(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_log_file_validation_enabled.cloudtrail_log_file_validation_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_log_file_validation_enabled.cloudtrail_log_file_validation_enabled import (
|
||||
cloudtrail_log_file_validation_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_log_file_validation_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search("log file validation disabled", result[0].status_extended)
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_various_trails_with_and_without_logging_validation(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
cloudtrail_client_eu_west_1 = client("cloudtrail", region_name="eu-west-1")
|
||||
s3_client_eu_west_1 = client("s3", region_name="eu-west-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
trail_name_eu = "trail_test_eu"
|
||||
bucket_name_eu = "bucket_test_eu"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
s3_client_eu_west_1.create_bucket(
|
||||
Bucket=bucket_name_eu,
|
||||
CreateBucketConfiguration={"LocationConstraint": "eu-west-1"},
|
||||
)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us,
|
||||
S3BucketName=bucket_name_us,
|
||||
IsMultiRegionTrail=False,
|
||||
EnableLogFileValidation=True,
|
||||
)
|
||||
trail_eu = cloudtrail_client_eu_west_1.create_trail(
|
||||
Name=trail_name_eu, S3BucketName=bucket_name_eu, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_log_file_validation_enabled.cloudtrail_log_file_validation_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_log_file_validation_enabled.cloudtrail_log_file_validation_enabled import (
|
||||
cloudtrail_log_file_validation_enabled,
|
||||
)
|
||||
|
||||
regions = []
|
||||
for region in service_client.regional_clients.keys():
|
||||
regions.append(region)
|
||||
|
||||
check = cloudtrail_log_file_validation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 2
|
||||
for report in result:
|
||||
if report.resource_id == trail_name_us:
|
||||
assert report.status == "PASS"
|
||||
assert search("log file validation enabled", report.status_extended)
|
||||
assert report.resource_id == trail_name_us
|
||||
assert report.resource_arn == trail_us["TrailARN"]
|
||||
elif report.resource_id == trail_name_eu:
|
||||
assert report.status == "FAIL"
|
||||
assert search(
|
||||
"log file validation disabled", report.status_extended
|
||||
)
|
||||
assert report.resource_id == trail_name_eu
|
||||
assert report.resource_arn == trail_eu["TrailARN"]
|
||||
@@ -0,0 +1,117 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
|
||||
|
||||
class Test_cloudtrail_logs_s3_bucket_access_logging_enabled:
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_bucket_not_logging(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
from prowler.providers.aws.services.s3.s3_service import S3
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled.s3_client",
|
||||
new=S3(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled import (
|
||||
cloudtrail_logs_s3_bucket_access_logging_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_logs_s3_bucket_access_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"S3 bucket access logging is not enabled for bucket",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_bucket_logging(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
logging_bucket = "logging"
|
||||
s3_client_us_east_1.create_bucket(
|
||||
Bucket=bucket_name_us,
|
||||
)
|
||||
s3_client_us_east_1.create_bucket(
|
||||
Bucket=logging_bucket,
|
||||
)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
s3_client_us_east_1.put_bucket_acl(
|
||||
Bucket=logging_bucket,
|
||||
GrantWrite="uri=http://acs.amazonaws.com/groups/s3/LogDelivery",
|
||||
GrantReadACP="uri=http://acs.amazonaws.com/groups/s3/LogDelivery",
|
||||
)
|
||||
s3_client_us_east_1.put_bucket_logging(
|
||||
Bucket=bucket_name_us,
|
||||
BucketLoggingStatus={
|
||||
"LoggingEnabled": {
|
||||
"TargetBucket": logging_bucket,
|
||||
"TargetPrefix": logging_bucket,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
from prowler.providers.aws.services.s3.s3_service import S3
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled.s3_client",
|
||||
new=S3(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled import (
|
||||
cloudtrail_logs_s3_bucket_access_logging_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_logs_s3_bucket_access_logging_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"S3 bucket access logging is enabled for bucket",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
@@ -0,0 +1,173 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
|
||||
|
||||
class Test_cloudtrail_logs_s3_bucket_is_not_publicly_accessible:
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_bucket_no_acl(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client.create_bucket(Bucket=bucket_name_us)
|
||||
trail_us = cloudtrail_client.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
from prowler.providers.aws.services.s3.s3_service import S3
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_access_logging_enabled.cloudtrail_logs_s3_bucket_access_logging_enabled.s3_client",
|
||||
new=S3(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible import (
|
||||
cloudtrail_logs_s3_bucket_is_not_publicly_accessible,
|
||||
)
|
||||
|
||||
check = cloudtrail_logs_s3_bucket_is_not_publicly_accessible()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
assert search(
|
||||
result[0].status_extended,
|
||||
f"S3 Bucket {bucket_name_us} from single region trail {trail_name_us} is not publicly accessible",
|
||||
)
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_bucket_public_acl(self):
|
||||
s3_client = client("s3", region_name="us-east-1")
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client.create_bucket(Bucket=bucket_name_us)
|
||||
s3_client.put_bucket_acl(
|
||||
AccessControlPolicy={
|
||||
"Grants": [
|
||||
{
|
||||
"Grantee": {
|
||||
"DisplayName": "test",
|
||||
"EmailAddress": "",
|
||||
"ID": "test_ID",
|
||||
"Type": "Group",
|
||||
"URI": "http://acs.amazonaws.com/groups/global/AllUsers",
|
||||
},
|
||||
"Permission": "READ",
|
||||
},
|
||||
],
|
||||
"Owner": {"DisplayName": "test", "ID": "test_id"},
|
||||
},
|
||||
Bucket=bucket_name_us,
|
||||
)
|
||||
|
||||
trail_name_us = "trail_test_us"
|
||||
cloudtrail_client = client("cloudtrail", region_name="us-east-1")
|
||||
trail_us = cloudtrail_client.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
from prowler.providers.aws.services.s3.s3_service import S3
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.s3_client",
|
||||
new=S3(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible import (
|
||||
cloudtrail_logs_s3_bucket_is_not_publicly_accessible,
|
||||
)
|
||||
|
||||
check = cloudtrail_logs_s3_bucket_is_not_publicly_accessible()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
assert search(
|
||||
result[0].status_extended,
|
||||
f"S3 Bucket {bucket_name_us} from single region trail {trail_name_us} is publicly accessible",
|
||||
)
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_bucket_not_public_acl(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client.create_bucket(Bucket=bucket_name_us)
|
||||
trail_us = cloudtrail_client.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
s3_client.put_bucket_acl(
|
||||
AccessControlPolicy={
|
||||
"Grants": [
|
||||
{
|
||||
"Grantee": {
|
||||
"DisplayName": "test",
|
||||
"EmailAddress": "",
|
||||
"ID": "test_ID",
|
||||
"Type": "CanonicalUser",
|
||||
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers",
|
||||
},
|
||||
"Permission": "READ",
|
||||
},
|
||||
],
|
||||
"Owner": {"DisplayName": "test", "ID": "test_id"},
|
||||
},
|
||||
Bucket=bucket_name_us,
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_logs_s3_bucket_is_not_publicly_accessible.cloudtrail_logs_s3_bucket_is_not_publicly_accessible import (
|
||||
cloudtrail_logs_s3_bucket_is_not_publicly_accessible,
|
||||
)
|
||||
|
||||
check = cloudtrail_logs_s3_bucket_is_not_publicly_accessible()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
assert search(
|
||||
result[0].status_extended,
|
||||
f"S3 Bucket {bucket_name_us} from single region trail {trail_name_us} is not publicly accessible",
|
||||
)
|
||||
@@ -0,0 +1,161 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
|
||||
|
||||
class Test_cloudtrail_multi_region_enabled:
|
||||
@mock_cloudtrail
|
||||
def test_no_trails(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled.cloudtrail_multi_region_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled.cloudtrail_multi_region_enabled import (
|
||||
cloudtrail_multi_region_enabled,
|
||||
)
|
||||
|
||||
regions = []
|
||||
for region in service_client.regional_clients.keys():
|
||||
regions.append(region)
|
||||
|
||||
check = cloudtrail_multi_region_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == len(regions)
|
||||
for report in result:
|
||||
assert report.status == "FAIL"
|
||||
assert search(
|
||||
"No CloudTrail trails enabled and logging were found",
|
||||
report.status_extended,
|
||||
)
|
||||
assert report.resource_id == "No trails"
|
||||
assert report.resource_arn == "No trails"
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_various_trails_no_login(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
cloudtrail_client_eu_west_1 = client("cloudtrail", region_name="eu-west-1")
|
||||
s3_client_eu_west_1 = client("s3", region_name="eu-west-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
trail_name_eu = "trail_test_eu"
|
||||
bucket_name_eu = "bucket_test_eu"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
s3_client_eu_west_1.create_bucket(
|
||||
Bucket=bucket_name_eu,
|
||||
CreateBucketConfiguration={"LocationConstraint": "eu-west-1"},
|
||||
)
|
||||
_ = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
_ = cloudtrail_client_eu_west_1.create_trail(
|
||||
Name=trail_name_eu, S3BucketName=bucket_name_eu, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled.cloudtrail_multi_region_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled.cloudtrail_multi_region_enabled import (
|
||||
cloudtrail_multi_region_enabled,
|
||||
)
|
||||
|
||||
regions = []
|
||||
for region in service_client.regional_clients.keys():
|
||||
regions.append(region)
|
||||
|
||||
check = cloudtrail_multi_region_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == len(regions)
|
||||
for report in result:
|
||||
assert report.status == "FAIL"
|
||||
assert search(
|
||||
"No CloudTrail trails enabled and logging were found",
|
||||
report.status_extended,
|
||||
)
|
||||
assert report.resource_id == "No trails"
|
||||
assert report.resource_arn == "No trails"
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_various_trails_with_and_without_login(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
cloudtrail_client_eu_west_1 = client("cloudtrail", region_name="eu-west-1")
|
||||
s3_client_eu_west_1 = client("s3", region_name="eu-west-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
trail_name_eu = "trail_test_eu"
|
||||
bucket_name_eu = "bucket_test_eu"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
s3_client_eu_west_1.create_bucket(
|
||||
Bucket=bucket_name_eu,
|
||||
CreateBucketConfiguration={"LocationConstraint": "eu-west-1"},
|
||||
)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
cloudtrail_client_eu_west_1.create_trail(
|
||||
Name=trail_name_eu, S3BucketName=bucket_name_eu, IsMultiRegionTrail=False
|
||||
)
|
||||
_ = cloudtrail_client_us_east_1.start_logging(Name=trail_name_us)
|
||||
_ = cloudtrail_client_us_east_1.get_trail_status(Name=trail_name_us)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled.cloudtrail_multi_region_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
) as service_client:
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_multi_region_enabled.cloudtrail_multi_region_enabled import (
|
||||
cloudtrail_multi_region_enabled,
|
||||
)
|
||||
|
||||
regions = []
|
||||
for region in service_client.regional_clients.keys():
|
||||
regions.append(region)
|
||||
|
||||
check = cloudtrail_multi_region_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == len(regions)
|
||||
for report in result:
|
||||
if report.resource_id == trail_name_us:
|
||||
assert report.status == "PASS"
|
||||
assert search(
|
||||
"is not multiregion and it is logging", report.status_extended
|
||||
)
|
||||
assert report.resource_id == trail_name_us
|
||||
assert report.resource_arn == trail_us["TrailARN"]
|
||||
else:
|
||||
assert report.status == "FAIL"
|
||||
assert search(
|
||||
"No CloudTrail trails enabled and logging were found",
|
||||
report.status_extended,
|
||||
)
|
||||
assert report.resource_id == "No trails"
|
||||
assert report.resource_arn == "No trails"
|
||||
@@ -0,0 +1,149 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
|
||||
|
||||
class Test_cloudtrail_s3_dataevents_read_enabled:
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_without_data_events(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import (
|
||||
cloudtrail_s3_dataevents_read_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_s3_dataevents_read_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"No CloudTrail trails have a data event to record all S3 object-level API operations.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "No trails"
|
||||
assert result[0].resource_arn == "No trails"
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_without_s3_data_events(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
_ = cloudtrail_client_us_east_1.put_event_selectors(
|
||||
TrailName=trail_name_us,
|
||||
EventSelectors=[
|
||||
{
|
||||
"ReadWriteType": "All",
|
||||
"IncludeManagementEvents": True,
|
||||
"DataResources": [
|
||||
{"Type": "AWS::Lambda::Function", "Values": ["arn:aws:lambda"]}
|
||||
],
|
||||
}
|
||||
],
|
||||
)["EventSelectors"]
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import (
|
||||
cloudtrail_s3_dataevents_read_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_s3_dataevents_read_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"No CloudTrail trails have a data event to record all S3 object-level API operations.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "No trails"
|
||||
assert result[0].resource_arn == "No trails"
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_with_s3_data_events(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
_ = cloudtrail_client_us_east_1.put_event_selectors(
|
||||
TrailName=trail_name_us,
|
||||
EventSelectors=[
|
||||
{
|
||||
"ReadWriteType": "All",
|
||||
"IncludeManagementEvents": True,
|
||||
"DataResources": [
|
||||
{"Type": "AWS::S3::Object", "Values": ["arn:aws:s3:::*/*"]}
|
||||
],
|
||||
}
|
||||
],
|
||||
)["EventSelectors"]
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import (
|
||||
cloudtrail_s3_dataevents_read_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_s3_dataevents_read_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"have a data event to record all S3 object-level API operations.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
@@ -0,0 +1,149 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
|
||||
|
||||
class Test_cloudtrail_s3_dataevents_write_enabled:
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_without_data_events(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import (
|
||||
cloudtrail_s3_dataevents_write_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_s3_dataevents_write_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"No CloudTrail trails have a data event to record all S3 object-level API operations.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "No trails"
|
||||
assert result[0].resource_arn == "No trails"
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_without_s3_data_events(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
_ = cloudtrail_client_us_east_1.put_event_selectors(
|
||||
TrailName=trail_name_us,
|
||||
EventSelectors=[
|
||||
{
|
||||
"ReadWriteType": "All",
|
||||
"IncludeManagementEvents": True,
|
||||
"DataResources": [
|
||||
{"Type": "AWS::Lambda::Function", "Values": ["arn:aws:lambda"]}
|
||||
],
|
||||
}
|
||||
],
|
||||
)["EventSelectors"]
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import (
|
||||
cloudtrail_s3_dataevents_write_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_s3_dataevents_write_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"No CloudTrail trails have a data event to record all S3 object-level API operations.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "No trails"
|
||||
assert result[0].resource_arn == "No trails"
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_trail_with_s3_data_events(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
trail_us = cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
_ = cloudtrail_client_us_east_1.put_event_selectors(
|
||||
TrailName=trail_name_us,
|
||||
EventSelectors=[
|
||||
{
|
||||
"ReadWriteType": "All",
|
||||
"IncludeManagementEvents": True,
|
||||
"DataResources": [
|
||||
{"Type": "AWS::S3::Object", "Values": ["arn:aws:s3:::*/*"]}
|
||||
],
|
||||
}
|
||||
],
|
||||
)["EventSelectors"]
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import (
|
||||
cloudtrail_s3_dataevents_write_enabled,
|
||||
)
|
||||
|
||||
check = cloudtrail_s3_dataevents_write_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"have a data event to record all S3 object-level API operations.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == trail_name_us
|
||||
assert result[0].resource_arn == trail_us["TrailARN"]
|
||||
@@ -0,0 +1,186 @@
|
||||
from boto3 import client, session
|
||||
from moto import mock_cloudtrail, mock_s3
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import Cloudtrail
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
|
||||
|
||||
class Test_Cloudtrail_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test Cloudtrail Service
|
||||
@mock_cloudtrail
|
||||
def test_service(self):
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudtrail = Cloudtrail(audit_info)
|
||||
assert cloudtrail.service == "cloudtrail"
|
||||
|
||||
# Test Cloudtrail client
|
||||
@mock_cloudtrail
|
||||
def test_client(self):
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudtrail = Cloudtrail(audit_info)
|
||||
for regional_client in cloudtrail.regional_clients.values():
|
||||
assert regional_client.__class__.__name__ == "CloudTrail"
|
||||
|
||||
# Test Cloudtrail session
|
||||
@mock_cloudtrail
|
||||
def test__get_session__(self):
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudtrail = Cloudtrail(audit_info)
|
||||
assert cloudtrail.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test Cloudtrail Session
|
||||
@mock_cloudtrail
|
||||
def test_audited_account(self):
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudtrail = Cloudtrail(audit_info)
|
||||
assert cloudtrail.audited_account == AWS_ACCOUNT_NUMBER
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_describe_trails(self):
|
||||
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
cloudtrail_client_eu_west_1 = client("cloudtrail", region_name="eu-west-1")
|
||||
s3_client_eu_west_1 = client("s3", region_name="eu-west-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
trail_name_eu = "trail_test_eu"
|
||||
bucket_name_eu = "bucket_test_eu"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
s3_client_eu_west_1.create_bucket(
|
||||
Bucket=bucket_name_eu,
|
||||
CreateBucketConfiguration={"LocationConstraint": "eu-west-1"},
|
||||
)
|
||||
cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us, S3BucketName=bucket_name_us, IsMultiRegionTrail=False
|
||||
)
|
||||
cloudtrail_client_eu_west_1.create_trail(
|
||||
Name=trail_name_eu, S3BucketName=bucket_name_eu, IsMultiRegionTrail=False
|
||||
)
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudtrail = Cloudtrail(audit_info)
|
||||
# 1 None result per region plus 2 created
|
||||
assert len(cloudtrail.trails) == 25
|
||||
for trail in cloudtrail.trails:
|
||||
if trail.name:
|
||||
assert trail.name == trail_name_us or trail.name == trail_name_eu
|
||||
assert not trail.is_multiregion
|
||||
assert (
|
||||
trail.home_region == "us-east-1" or trail.home_region == "eu-west-1"
|
||||
)
|
||||
assert trail.region == "us-east-1" or trail.region == "eu-west-1"
|
||||
assert not trail.is_logging
|
||||
assert not trail.log_file_validation_enabled
|
||||
assert not trail.latest_cloudwatch_delivery_time
|
||||
assert (
|
||||
trail.s3_bucket == bucket_name_eu
|
||||
or trail.s3_bucket == bucket_name_us
|
||||
)
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_status_trails(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
cloudtrail_client_eu_west_1 = client("cloudtrail", region_name="eu-west-1")
|
||||
s3_client_eu_west_1 = client("s3", region_name="eu-west-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
trail_name_eu = "trail_test_eu"
|
||||
bucket_name_eu = "bucket_test_eu"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
s3_client_eu_west_1.create_bucket(
|
||||
Bucket=bucket_name_eu,
|
||||
CreateBucketConfiguration={"LocationConstraint": "eu-west-1"},
|
||||
)
|
||||
cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us,
|
||||
S3BucketName=bucket_name_us,
|
||||
IsMultiRegionTrail=False,
|
||||
EnableLogFileValidation=True,
|
||||
)
|
||||
cloudtrail_client_us_east_1.start_logging(Name=trail_name_us)
|
||||
cloudtrail_client_eu_west_1.create_trail(
|
||||
Name=trail_name_eu, S3BucketName=bucket_name_eu, IsMultiRegionTrail=False
|
||||
)
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudtrail = Cloudtrail(audit_info)
|
||||
# 1 None result per region plus 2 created
|
||||
assert len(cloudtrail.trails) == 25
|
||||
for trail in cloudtrail.trails:
|
||||
if trail.name:
|
||||
if trail.name == trail_name_us:
|
||||
assert not trail.is_multiregion
|
||||
assert trail.home_region == "us-east-1"
|
||||
assert trail.region == "us-east-1"
|
||||
assert trail.is_logging
|
||||
assert trail.log_file_validation_enabled
|
||||
assert not trail.latest_cloudwatch_delivery_time
|
||||
assert trail.s3_bucket == bucket_name_us
|
||||
|
||||
@mock_cloudtrail
|
||||
@mock_s3
|
||||
def test_get_event_selectors(self):
|
||||
cloudtrail_client_us_east_1 = client("cloudtrail", region_name="us-east-1")
|
||||
s3_client_us_east_1 = client("s3", region_name="us-east-1")
|
||||
trail_name_us = "trail_test_us"
|
||||
bucket_name_us = "bucket_test_us"
|
||||
s3_client_us_east_1.create_bucket(Bucket=bucket_name_us)
|
||||
cloudtrail_client_us_east_1.create_trail(
|
||||
Name=trail_name_us,
|
||||
S3BucketName=bucket_name_us,
|
||||
IsMultiRegionTrail=False,
|
||||
EnableLogFileValidation=True,
|
||||
)
|
||||
cloudtrail_client_us_east_1.start_logging(Name=trail_name_us)
|
||||
data_events_response = cloudtrail_client_us_east_1.put_event_selectors(
|
||||
TrailName=trail_name_us,
|
||||
EventSelectors=[
|
||||
{
|
||||
"ReadWriteType": "All",
|
||||
"IncludeManagementEvents": True,
|
||||
"DataResources": [
|
||||
{"Type": "AWS::S3::Object", "Values": ["arn:aws:s3:::*/*"]}
|
||||
],
|
||||
}
|
||||
],
|
||||
)["EventSelectors"]
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudtrail = Cloudtrail(audit_info)
|
||||
# 1 None result per region plus 2 created
|
||||
assert len(cloudtrail.trails) == 25
|
||||
for trail in cloudtrail.trails:
|
||||
if trail.name:
|
||||
if trail.name == trail_name_us:
|
||||
assert not trail.is_multiregion
|
||||
assert trail.home_region == "us-east-1"
|
||||
assert trail.region == "us-east-1"
|
||||
assert trail.is_logging
|
||||
assert trail.log_file_validation_enabled
|
||||
assert not trail.latest_cloudwatch_delivery_time
|
||||
assert trail.s3_bucket == bucket_name_us
|
||||
assert trail.data_events == data_events_response
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured import (
|
||||
cloudwatch_changes_to_network_acls_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_acls_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured import (
|
||||
cloudwatch_changes_to_network_acls_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_acls_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured import (
|
||||
cloudwatch_changes_to_network_acls_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_acls_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured import (
|
||||
cloudwatch_changes_to_network_acls_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_acls_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_acls_alarm_configured.cloudwatch_changes_to_network_acls_alarm_configured import (
|
||||
cloudwatch_changes_to_network_acls_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_acls_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured import (
|
||||
cloudwatch_changes_to_network_gateways_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_gateways_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured import (
|
||||
cloudwatch_changes_to_network_gateways_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_gateways_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured import (
|
||||
cloudwatch_changes_to_network_gateways_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_gateways_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured import (
|
||||
cloudwatch_changes_to_network_gateways_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_gateways_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_gateways_alarm_configured.cloudwatch_changes_to_network_gateways_alarm_configured import (
|
||||
cloudwatch_changes_to_network_gateways_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_gateways_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured import (
|
||||
cloudwatch_changes_to_network_route_tables_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_route_tables_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured import (
|
||||
cloudwatch_changes_to_network_route_tables_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_route_tables_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured import (
|
||||
cloudwatch_changes_to_network_route_tables_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_route_tables_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation)|| ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured import (
|
||||
cloudwatch_changes_to_network_route_tables_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_route_tables_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation)|| ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_network_route_tables_alarm_configured.cloudwatch_changes_to_network_route_tables_alarm_configured import (
|
||||
cloudwatch_changes_to_network_route_tables_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_network_route_tables_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured import (
|
||||
cloudwatch_changes_to_vpcs_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_vpcs_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured import (
|
||||
cloudwatch_changes_to_vpcs_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_vpcs_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured import (
|
||||
cloudwatch_changes_to_vpcs_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_vpcs_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured import (
|
||||
cloudwatch_changes_to_vpcs_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_vpcs_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_changes_to_vpcs_alarm_configured.cloudwatch_changes_to_vpcs_alarm_configured import (
|
||||
cloudwatch_changes_to_vpcs_alarm_configured,
|
||||
)
|
||||
|
||||
check = cloudwatch_changes_to_vpcs_alarm_configured()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,68 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_iam
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_cross_account_sharing_disabled:
|
||||
@mock_iam
|
||||
def test_cloudwatch_without_cross_account_role(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_cross_account_sharing_disabled.cloudwatch_cross_account_sharing_disabled.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_cross_account_sharing_disabled.cloudwatch_cross_account_sharing_disabled import (
|
||||
cloudwatch_cross_account_sharing_disabled,
|
||||
)
|
||||
|
||||
check = cloudwatch_cross_account_sharing_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch doesn't allows cross-account sharing"
|
||||
)
|
||||
assert result[0].resource_id == "CloudWatch-CrossAccountSharingRole"
|
||||
|
||||
@mock_iam
|
||||
def test_cloudwatch_log_group_with_cross_account_role(self):
|
||||
# Generate Logs Client
|
||||
iam_client = client("iam", region_name=AWS_REGION)
|
||||
# Request Logs group
|
||||
iam_client.create_role(
|
||||
RoleName="CloudWatch-CrossAccountSharingRole", AssumeRolePolicyDocument="{}"
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_cross_account_sharing_disabled.cloudwatch_cross_account_sharing_disabled.iam_client",
|
||||
new=IAM(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_cross_account_sharing_disabled.cloudwatch_cross_account_sharing_disabled import (
|
||||
cloudwatch_cross_account_sharing_disabled,
|
||||
)
|
||||
|
||||
check = cloudwatch_cross_account_sharing_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch has allowed cross-account sharing."
|
||||
)
|
||||
assert result[0].resource_id == "CloudWatch-CrossAccountSharingRole"
|
||||
@@ -0,0 +1,92 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_logs
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_group_kms_encryption_enabled:
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_kms_encryption_enabled.cloudwatch_log_group_kms_encryption_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_kms_encryption_enabled.cloudwatch_log_group_kms_encryption_enabled import (
|
||||
cloudwatch_log_group_kms_encryption_enabled,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_group_kms_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_logs
|
||||
def test_cloudwatch_log_group_without_kms_key(self):
|
||||
# Generate Logs Client
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
# Request Logs group
|
||||
logs_client.create_log_group(
|
||||
logGroupName="test",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_kms_encryption_enabled.cloudwatch_log_group_kms_encryption_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_kms_encryption_enabled.cloudwatch_log_group_kms_encryption_enabled import (
|
||||
cloudwatch_log_group_kms_encryption_enabled,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_group_kms_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Log Group test does not have AWS KMS keys associated."
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
|
||||
@mock_logs
|
||||
def test_cloudwatch_log_group_with_kms_key(self):
|
||||
# Generate Logs Client
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
# Request Logs group
|
||||
logs_client.create_log_group(logGroupName="test", kmsKeyId="test_kms_id")
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_kms_encryption_enabled.cloudwatch_log_group_kms_encryption_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_kms_encryption_enabled.cloudwatch_log_group_kms_encryption_enabled import (
|
||||
cloudwatch_log_group_kms_encryption_enabled,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_group_kms_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Log Group test does have AWS KMS key test_kms_id associated."
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
@@ -0,0 +1,129 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_logs
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_group_retention_policy_specific_days_enabled:
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled import (
|
||||
cloudwatch_log_group_retention_policy_specific_days_enabled,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_group_retention_policy_specific_days_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_logs
|
||||
def test_cloudwatch_log_group_without_retention_days(self):
|
||||
# Generate Logs Client
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
# Request Logs group
|
||||
logs_client.create_log_group(
|
||||
logGroupName="test",
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled import (
|
||||
cloudwatch_log_group_retention_policy_specific_days_enabled,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_group_retention_policy_specific_days_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Log Group test has less than 365 days retention period (0 days)."
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
|
||||
@mock_logs
|
||||
def test_cloudwatch_log_group_with_compliant_retention_days(self):
|
||||
# Generate Logs Client
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
# Request Logs group
|
||||
logs_client.create_log_group(
|
||||
logGroupName="test",
|
||||
)
|
||||
logs_client.put_retention_policy(logGroupName="test", retentionInDays=400)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled import (
|
||||
cloudwatch_log_group_retention_policy_specific_days_enabled,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_group_retention_policy_specific_days_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Log Group test comply with 365 days retention period since it has 400 days."
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
|
||||
@mock_logs
|
||||
def test_cloudwatch_log_group_with_no_compliant_retention_days(self):
|
||||
# Generate Logs Client
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
# Request Logs group
|
||||
logs_client.create_log_group(
|
||||
logGroupName="test",
|
||||
)
|
||||
logs_client.put_retention_policy(logGroupName="test", retentionInDays=7)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_group_retention_policy_specific_days_enabled.cloudwatch_log_group_retention_policy_specific_days_enabled import (
|
||||
cloudwatch_log_group_retention_policy_specific_days_enabled,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_group_retention_policy_specific_days_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Log Group test has less than 365 days retention period (7 days)."
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
@@ -0,0 +1,302 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)|| ($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder))}",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)|| ($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder))}",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,302 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging)}",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging)}",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled.cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled import (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures import (
|
||||
cloudwatch_log_metric_filter_authentication_failures,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_authentication_failures()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures import (
|
||||
cloudwatch_log_metric_filter_authentication_failures,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_authentication_failures()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures import (
|
||||
cloudwatch_log_metric_filter_authentication_failures,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_authentication_failures()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = ConsoleLogin) && ($.errorMessage = Failed authentication)}",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures import (
|
||||
cloudwatch_log_metric_filter_authentication_failures,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_authentication_failures()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = ConsoleLogin) && ($.errorMessage = Failed authentication)}",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_authentication_failures.cloudwatch_log_metric_filter_authentication_failures import (
|
||||
cloudwatch_log_metric_filter_authentication_failures,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_authentication_failures()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_aws_organizations_changes:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes import (
|
||||
cloudwatch_log_metric_filter_aws_organizations_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_aws_organizations_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes import (
|
||||
cloudwatch_log_metric_filter_aws_organizations_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_aws_organizations_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes import (
|
||||
cloudwatch_log_metric_filter_aws_organizations_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_aws_organizations_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.eventSource = organizations.amazonaws.com) && ($.eventName = AcceptHandshake) || ($.eventName = AttachPolicy) || ($.eventName = CancelHandshake) || ($.eventName = CreateAccount) || ($.eventName = CreateOrganization) || ($.eventName = CreateOrganizationalUnit) || ($.eventName = CreatePolicy) || ($.eventName = DeclineHandshake) || ($.eventName = DeleteOrganization) || ($.eventName = DeleteOrganizationalUnit) || ($.eventName = DeletePolicy) || ($.eventName = EnableAllFeatures) || ($.eventName = EnablePolicyType) || ($.eventName = InviteAccountToOrganization) || ($.eventName = LeaveOrganization) || ($.eventName = DetachPolicy) || ($.eventName = DisablePolicyType) || ($.eventName = MoveAccount) || ($.eventName = RemoveAccountFromOrganization) || ($.eventName = UpdateOrganizationalUnit) || ($.eventName = UpdatePolicy) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes import (
|
||||
cloudwatch_log_metric_filter_aws_organizations_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_aws_organizations_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.eventSource = organizations.amazonaws.com) && ($.eventName = AcceptHandshake) || ($.eventName = AttachPolicy) || ($.eventName = CancelHandshake) || ($.eventName = CreateAccount) || ($.eventName = CreateOrganization) || ($.eventName = CreateOrganizationalUnit) || ($.eventName = CreatePolicy) || ($.eventName = DeclineHandshake) || ($.eventName = DeleteOrganization) || ($.eventName = DeleteOrganizationalUnit) || ($.eventName = DeletePolicy) || ($.eventName = EnableAllFeatures) || ($.eventName = EnablePolicyType) || ($.eventName = InviteAccountToOrganization) || ($.eventName = LeaveOrganization) || ($.eventName = DetachPolicy) || ($.eventName = DisablePolicyType) || ($.eventName = MoveAccount) || ($.eventName = RemoveAccountFromOrganization) || ($.eventName = UpdateOrganizationalUnit) || ($.eventName = UpdatePolicy) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_aws_organizations_changes.cloudwatch_log_metric_filter_aws_organizations_changes import (
|
||||
cloudwatch_log_metric_filter_aws_organizations_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_aws_organizations_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,302 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk import (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk import (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk import (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventSource = kms.amazonaws.com) &&(($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk import (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventSource = kms.amazonaws.com) &&(($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk.cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk import (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk,
|
||||
)
|
||||
|
||||
check = (
|
||||
cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk()
|
||||
)
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes import (
|
||||
cloudwatch_log_metric_filter_for_s3_bucket_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_for_s3_bucket_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes import (
|
||||
cloudwatch_log_metric_filter_for_s3_bucket_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_for_s3_bucket_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes import (
|
||||
cloudwatch_log_metric_filter_for_s3_bucket_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_for_s3_bucket_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes import (
|
||||
cloudwatch_log_metric_filter_for_s3_bucket_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_for_s3_bucket_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes.cloudwatch_log_metric_filter_for_s3_bucket_policy_changes import (
|
||||
cloudwatch_log_metric_filter_for_s3_bucket_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_for_s3_bucket_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes import (
|
||||
cloudwatch_log_metric_filter_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes import (
|
||||
cloudwatch_log_metric_filter_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes import (
|
||||
cloudwatch_log_metric_filter_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes import (
|
||||
cloudwatch_log_metric_filter_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_policy_changes.cloudwatch_log_metric_filter_policy_changes import (
|
||||
cloudwatch_log_metric_filter_policy_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_policy_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage import (
|
||||
cloudwatch_log_metric_filter_root_usage,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_root_usage()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage import (
|
||||
cloudwatch_log_metric_filter_root_usage,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_root_usage()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage import (
|
||||
cloudwatch_log_metric_filter_root_usage,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_root_usage()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ $.userIdentity.type = Root && $.userIdentity.invokedBy NOT EXISTS && $.eventType != AwsServiceEvent }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage import (
|
||||
cloudwatch_log_metric_filter_root_usage,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_root_usage()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ $.userIdentity.type = Root && $.userIdentity.invokedBy NOT EXISTS && $.eventType != AwsServiceEvent }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_root_usage.cloudwatch_log_metric_filter_root_usage import (
|
||||
cloudwatch_log_metric_filter_root_usage,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_root_usage()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes import (
|
||||
cloudwatch_log_metric_filter_security_group_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_security_group_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes import (
|
||||
cloudwatch_log_metric_filter_security_group_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_security_group_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes import (
|
||||
cloudwatch_log_metric_filter_security_group_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_security_group_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes import (
|
||||
cloudwatch_log_metric_filter_security_group_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_security_group_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_security_group_changes.cloudwatch_log_metric_filter_security_group_changes import (
|
||||
cloudwatch_log_metric_filter_security_group_changes,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_security_group_changes()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa import (
|
||||
cloudwatch_log_metric_filter_sign_in_without_mfa,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_sign_in_without_mfa()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa import (
|
||||
cloudwatch_log_metric_filter_sign_in_without_mfa,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_sign_in_without_mfa()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa import (
|
||||
cloudwatch_log_metric_filter_sign_in_without_mfa,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_sign_in_without_mfa()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.eventName = ConsoleLogin) && ($.additionalEventData.MFAUsed != Yes) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa import (
|
||||
cloudwatch_log_metric_filter_sign_in_without_mfa,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_sign_in_without_mfa()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.eventName = ConsoleLogin) && ($.additionalEventData.MFAUsed != Yes) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_sign_in_without_mfa.cloudwatch_log_metric_filter_sign_in_without_mfa import (
|
||||
cloudwatch_log_metric_filter_sign_in_without_mfa,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_sign_in_without_mfa()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,292 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_cloudtrail, mock_cloudwatch, mock_logs, mock_s3
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_cloudwatch_log_metric_filter_unauthorized_api_calls:
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
def test_cloudwatch_no_log_groups(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls import (
|
||||
cloudwatch_log_metric_filter_unauthorized_api_calls,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_unauthorized_api_calls()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_no_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
cloudtrail_client.create_trail(Name="test_trail", S3BucketName="test")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls import (
|
||||
cloudwatch_log_metric_filter_unauthorized_api_calls,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_unauthorized_api_calls()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls import (
|
||||
cloudwatch_log_metric_filter_unauthorized_api_calls,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_unauthorized_api_calls()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "No CloudWatch log groups found with metric filters or alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls import (
|
||||
cloudwatch_log_metric_filter_unauthorized_api_calls,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_unauthorized_api_calls()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter but no alarms associated."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
|
||||
@mock_logs
|
||||
@mock_cloudtrail
|
||||
@mock_cloudwatch
|
||||
@mock_s3
|
||||
def test_cloudwatch_trail_with_log_group_with_metric_and_alarm(self):
|
||||
cloudtrail_client = client("cloudtrail", region_name=AWS_REGION)
|
||||
cloudwatch_client = client("cloudwatch", region_name=AWS_REGION)
|
||||
logs_client = client("logs", region_name=AWS_REGION)
|
||||
s3_client = client("s3", region_name=AWS_REGION)
|
||||
s3_client.create_bucket(Bucket="test")
|
||||
logs_client.create_log_group(logGroupName="/log-group/test")
|
||||
cloudtrail_client.create_trail(
|
||||
Name="test_trail",
|
||||
S3BucketName="test",
|
||||
CloudWatchLogsLogGroupArn=f"arn:aws:logs:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:log-group:/log-group/test:*",
|
||||
)
|
||||
logs_client.put_metric_filter(
|
||||
logGroupName="/log-group/test",
|
||||
filterName="test-filter",
|
||||
filterPattern="{ ($.errorCode = *UnauthorizedOperation) || ($.errorCode = AccessDenied*) || ($.sourceIPAddress!=delivery.logs.amazonaws.com) || ($.eventName!=HeadBucket) }",
|
||||
metricTransformations=[
|
||||
{
|
||||
"metricName": "my-metric",
|
||||
"metricNamespace": "my-namespace",
|
||||
"metricValue": "$.value",
|
||||
}
|
||||
],
|
||||
)
|
||||
cloudwatch_client.put_metric_alarm(
|
||||
AlarmName="test-alarm",
|
||||
MetricName="my-metric",
|
||||
Namespace="my-namespace",
|
||||
Period=10,
|
||||
EvaluationPeriods=5,
|
||||
Statistic="Average",
|
||||
Threshold=2,
|
||||
ComparisonOperator="GreaterThanThreshold",
|
||||
ActionsEnabled=True,
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import (
|
||||
CloudWatch,
|
||||
Logs,
|
||||
)
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
|
||||
Cloudtrail,
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.logs_client",
|
||||
new=Logs(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_client",
|
||||
new=CloudWatch(current_audit_info),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudtrail_client",
|
||||
new=Cloudtrail(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_log_metric_filter_unauthorized_api_calls.cloudwatch_log_metric_filter_unauthorized_api_calls import (
|
||||
cloudwatch_log_metric_filter_unauthorized_api_calls,
|
||||
)
|
||||
|
||||
check = cloudwatch_log_metric_filter_unauthorized_api_calls()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "CloudWatch log group /log-group/test found with metric filter test-filter and alarms set."
|
||||
)
|
||||
assert result[0].resource_id == "/log-group/test"
|
||||
@@ -0,0 +1,64 @@
|
||||
from boto3 import session
|
||||
from moto import mock_cloudwatch
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import CloudWatch
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_CloudWatch_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test CloudWatch Service
|
||||
@mock_cloudwatch
|
||||
def test_service(self):
|
||||
# CloudWatch client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudwatch = CloudWatch(audit_info)
|
||||
assert cloudwatch.service == "cloudwatch"
|
||||
|
||||
# Test CloudWatch Client
|
||||
@mock_cloudwatch
|
||||
def test_client(self):
|
||||
# CloudWatch client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudwatch = CloudWatch(audit_info)
|
||||
for client in cloudwatch.regional_clients.values():
|
||||
assert client.__class__.__name__ == "CloudWatch"
|
||||
|
||||
# Test CloudWatch Session
|
||||
@mock_cloudwatch
|
||||
def test__get_session__(self):
|
||||
# CloudWatch client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudwatch = CloudWatch(audit_info)
|
||||
assert cloudwatch.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test CloudWatch Session
|
||||
@mock_cloudwatch
|
||||
def test_audited_account(self):
|
||||
# CloudWatch client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
cloudwatch = CloudWatch(audit_info)
|
||||
assert cloudwatch.audited_account == AWS_ACCOUNT_NUMBER
|
||||
@@ -0,0 +1,172 @@
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.codeartifact.codeartifact_service import (
|
||||
LatestPackageVersion,
|
||||
LatestPackageVersionStatus,
|
||||
OriginConfiguration,
|
||||
OriginInformation,
|
||||
OriginInformationValues,
|
||||
Package,
|
||||
Repository,
|
||||
Restrictions,
|
||||
RestrictionValues,
|
||||
)
|
||||
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_codeartifact_packages_external_public_publishing_disabled:
|
||||
def test_no_repositories(self):
|
||||
codeartifact_client = mock.MagicMock
|
||||
codeartifact_client.repositories = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codeartifact.codeartifact_service.CodeArtifact",
|
||||
new=codeartifact_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.codeartifact.codeartifact_packages_external_public_publishing_disabled.codeartifact_packages_external_public_publishing_disabled import (
|
||||
codeartifact_packages_external_public_publishing_disabled,
|
||||
)
|
||||
|
||||
check = codeartifact_packages_external_public_publishing_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_repository_without_packages(self):
|
||||
codeartifact_client = mock.MagicMock
|
||||
codeartifact_client.repositories = {
|
||||
"test-repository": Repository(
|
||||
name="test-repository",
|
||||
arn="",
|
||||
domain_name="",
|
||||
domain_owner="",
|
||||
region=AWS_REGION,
|
||||
packages=[],
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codeartifact.codeartifact_service.CodeArtifact",
|
||||
new=codeartifact_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.codeartifact.codeartifact_packages_external_public_publishing_disabled.codeartifact_packages_external_public_publishing_disabled import (
|
||||
codeartifact_packages_external_public_publishing_disabled,
|
||||
)
|
||||
|
||||
check = codeartifact_packages_external_public_publishing_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_repository_package_public_publishing_origin_internal(self):
|
||||
codeartifact_client = mock.MagicMock
|
||||
package_name = "test-package"
|
||||
package_namespace = "test-namespace"
|
||||
repository_arn = f"arn:aws:codebuild:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:repository/test-repository"
|
||||
codeartifact_client.repositories = {
|
||||
"test-repository": Repository(
|
||||
name="test-repository",
|
||||
arn=repository_arn,
|
||||
domain_name="",
|
||||
domain_owner="",
|
||||
region=AWS_REGION,
|
||||
packages=[
|
||||
Package(
|
||||
name=package_name,
|
||||
namespace=package_namespace,
|
||||
format="pypi",
|
||||
origin_configuration=OriginConfiguration(
|
||||
restrictions=Restrictions(
|
||||
publish=RestrictionValues.ALLOW,
|
||||
upstream=RestrictionValues.ALLOW,
|
||||
)
|
||||
),
|
||||
latest_version=LatestPackageVersion(
|
||||
version="latest",
|
||||
status=LatestPackageVersionStatus.Published,
|
||||
origin=OriginInformation(
|
||||
origin_type=OriginInformationValues.INTERNAL
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codeartifact.codeartifact_service.CodeArtifact",
|
||||
new=codeartifact_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.codeartifact.codeartifact_packages_external_public_publishing_disabled.codeartifact_packages_external_public_publishing_disabled import (
|
||||
codeartifact_packages_external_public_publishing_disabled,
|
||||
)
|
||||
|
||||
check = codeartifact_packages_external_public_publishing_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == "test-package"
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Internal package {package_namespace} {package_name} is vulnerable to dependency confusion in repository {repository_arn}"
|
||||
)
|
||||
|
||||
def test_repository_package_private_publishing_origin_internal(self):
|
||||
codeartifact_client = mock.MagicMock
|
||||
package_name = "test-package"
|
||||
package_namespace = "test-namespace"
|
||||
repository_arn = f"arn:aws:codebuild:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:repository/test-repository"
|
||||
codeartifact_client.repositories = {
|
||||
"test-repository": Repository(
|
||||
name="test-repository",
|
||||
arn=repository_arn,
|
||||
domain_name="",
|
||||
domain_owner="",
|
||||
region=AWS_REGION,
|
||||
packages=[
|
||||
Package(
|
||||
name=package_name,
|
||||
namespace=package_namespace,
|
||||
format="pypi",
|
||||
origin_configuration=OriginConfiguration(
|
||||
restrictions=Restrictions(
|
||||
publish=RestrictionValues.BLOCK,
|
||||
upstream=RestrictionValues.BLOCK,
|
||||
)
|
||||
),
|
||||
latest_version=LatestPackageVersion(
|
||||
version="latest",
|
||||
status=LatestPackageVersionStatus.Published,
|
||||
origin=OriginInformation(
|
||||
origin_type=OriginInformationValues.INTERNAL
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codeartifact.codeartifact_service.CodeArtifact",
|
||||
new=codeartifact_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.codeartifact.codeartifact_packages_external_public_publishing_disabled.codeartifact_packages_external_public_publishing_disabled import (
|
||||
codeartifact_packages_external_public_publishing_disabled,
|
||||
)
|
||||
|
||||
check = codeartifact_packages_external_public_publishing_disabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].resource_id == "test-package"
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Internal package {package_namespace} {package_name} is not vulnerable to dependency confusion in repository {repository_arn}"
|
||||
)
|
||||
@@ -0,0 +1,174 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
import botocore
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.codeartifact.codeartifact_service import (
|
||||
CodeArtifact,
|
||||
LatestPackageVersionStatus,
|
||||
OriginInformationValues,
|
||||
RestrictionValues,
|
||||
)
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
# Mocking Access Analyzer Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
"""We have to mock every AWS API call using Boto3"""
|
||||
if operation_name == "ListRepositories":
|
||||
return {
|
||||
"repositories": [
|
||||
{
|
||||
"name": "test-repository",
|
||||
"administratorAccount": DEFAULT_ACCOUNT_ID,
|
||||
"domainName": "test-domain",
|
||||
"domainOwner": DEFAULT_ACCOUNT_ID,
|
||||
"arn": f"arn:aws:codebuild:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:repository/test-repository",
|
||||
"description": "test description",
|
||||
},
|
||||
]
|
||||
}
|
||||
if operation_name == "ListPackages":
|
||||
return {
|
||||
"packages": [
|
||||
{
|
||||
"format": "pypi",
|
||||
"namespace": "test-namespace",
|
||||
"package": "test-package",
|
||||
"originConfiguration": {
|
||||
"restrictions": {
|
||||
"publish": "ALLOW",
|
||||
"upstream": "ALLOW",
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
if operation_name == "ListPackageVersions":
|
||||
return {
|
||||
"defaultDisplayVersion": "latest",
|
||||
"format": "pypi",
|
||||
"namespace": "test-namespace",
|
||||
"package": "test-package",
|
||||
"versions": [
|
||||
{
|
||||
"version": "latest",
|
||||
"revision": "lates",
|
||||
"status": "Published",
|
||||
"origin": {
|
||||
"domainEntryPoint": {
|
||||
"repositoryName": "test-repository",
|
||||
"externalConnectionName": "",
|
||||
},
|
||||
"originType": "INTERNAL",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
# Mock generate_regional_clients()
|
||||
def mock_generate_regional_clients(service, audit_info):
|
||||
regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION)
|
||||
regional_client.region = AWS_REGION
|
||||
return {AWS_REGION: regional_client}
|
||||
|
||||
|
||||
# Patch every AWS call using Boto3 and generate_regional_clients to have 1 client
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
@patch(
|
||||
"prowler.providers.aws.services.codeartifact.codeartifact_service.generate_regional_clients",
|
||||
new=mock_generate_regional_clients,
|
||||
)
|
||||
class Test_CodeArtifact_Service:
|
||||
# Test CodeArtifact Client
|
||||
def test__get_client__(self):
|
||||
codeartifact = CodeArtifact(current_audit_info)
|
||||
assert (
|
||||
codeartifact.regional_clients[AWS_REGION].__class__.__name__
|
||||
== "CodeArtifact"
|
||||
)
|
||||
|
||||
# Test CodeArtifact Session
|
||||
def test__get_session__(self):
|
||||
codeartifact = CodeArtifact(current_audit_info)
|
||||
assert codeartifact.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test CodeArtifact Service
|
||||
def test__get_service__(self):
|
||||
codeartifact = CodeArtifact(current_audit_info)
|
||||
assert codeartifact.service == "codeartifact"
|
||||
|
||||
def test__list_repositories__(self):
|
||||
# Set partition for the service
|
||||
current_audit_info.audited_partition = "aws"
|
||||
codeartifact = CodeArtifact(current_audit_info)
|
||||
|
||||
assert len(codeartifact.repositories) == 1
|
||||
assert codeartifact.repositories
|
||||
assert codeartifact.repositories["test-repository"]
|
||||
assert codeartifact.repositories["test-repository"].name == "test-repository"
|
||||
assert (
|
||||
codeartifact.repositories["test-repository"].arn
|
||||
== f"arn:aws:codebuild:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:repository/test-repository"
|
||||
)
|
||||
assert codeartifact.repositories["test-repository"].domain_name == "test-domain"
|
||||
assert (
|
||||
codeartifact.repositories["test-repository"].domain_owner
|
||||
== DEFAULT_ACCOUNT_ID
|
||||
)
|
||||
assert codeartifact.repositories["test-repository"].region == AWS_REGION
|
||||
|
||||
assert codeartifact.repositories["test-repository"].packages
|
||||
assert len(codeartifact.repositories["test-repository"].packages) == 1
|
||||
assert (
|
||||
codeartifact.repositories["test-repository"].packages[0].name
|
||||
== "test-package"
|
||||
)
|
||||
assert (
|
||||
codeartifact.repositories["test-repository"].packages[0].namespace
|
||||
== "test-namespace"
|
||||
)
|
||||
|
||||
assert codeartifact.repositories["test-repository"].packages[0].format == "pypi"
|
||||
assert (
|
||||
codeartifact.repositories["test-repository"]
|
||||
.packages[0]
|
||||
.origin_configuration.restrictions.publish
|
||||
== RestrictionValues.ALLOW
|
||||
)
|
||||
assert (
|
||||
codeartifact.repositories["test-repository"]
|
||||
.packages[0]
|
||||
.origin_configuration.restrictions.upstream
|
||||
== RestrictionValues.ALLOW
|
||||
)
|
||||
|
||||
assert (
|
||||
codeartifact.repositories["test-repository"]
|
||||
.packages[0]
|
||||
.latest_version.version
|
||||
== "latest"
|
||||
)
|
||||
|
||||
assert (
|
||||
codeartifact.repositories["test-repository"]
|
||||
.packages[0]
|
||||
.latest_version.status
|
||||
== LatestPackageVersionStatus.Published
|
||||
)
|
||||
|
||||
assert (
|
||||
codeartifact.repositories["test-repository"]
|
||||
.packages[0]
|
||||
.latest_version.origin.origin_type
|
||||
== OriginInformationValues.INTERNAL
|
||||
)
|
||||
@@ -0,0 +1,89 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.codebuild.codebuild_service import CodebuildProject
|
||||
|
||||
|
||||
class Test_codebuild_project_older_90_days:
|
||||
def test_project_not_built_in_last_90_days(self):
|
||||
codebuild_client = mock.MagicMock
|
||||
codebuild_client.projects = [
|
||||
CodebuildProject(
|
||||
name="test",
|
||||
region="eu-west-1",
|
||||
last_invoked_time=datetime.now(timezone.utc) - timedelta(days=100),
|
||||
buildspec=None,
|
||||
)
|
||||
]
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
|
||||
codebuild_client,
|
||||
):
|
||||
from prowler.providers.aws.services.codebuild.codebuild_project_older_90_days.codebuild_project_older_90_days import (
|
||||
codebuild_project_older_90_days,
|
||||
)
|
||||
|
||||
check = codebuild_project_older_90_days()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"has not been invoked in the last 90 days", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
assert result[0].resource_arn == ""
|
||||
|
||||
def test_project_not_built(self):
|
||||
codebuild_client = mock.MagicMock
|
||||
codebuild_client.projects = [
|
||||
CodebuildProject(
|
||||
name="test", region="eu-west-1", last_invoked_time=None, buildspec=None
|
||||
)
|
||||
]
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
|
||||
codebuild_client,
|
||||
):
|
||||
from prowler.providers.aws.services.codebuild.codebuild_project_older_90_days.codebuild_project_older_90_days import (
|
||||
codebuild_project_older_90_days,
|
||||
)
|
||||
|
||||
check = codebuild_project_older_90_days()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search("has never been built", result[0].status_extended)
|
||||
assert result[0].resource_id == "test"
|
||||
assert result[0].resource_arn == ""
|
||||
|
||||
def test_project_built_in_last_90_days(self):
|
||||
codebuild_client = mock.MagicMock
|
||||
codebuild_client.projects = [
|
||||
CodebuildProject(
|
||||
name="test",
|
||||
region="eu-west-1",
|
||||
last_invoked_time=datetime.now(timezone.utc) - timedelta(days=10),
|
||||
buildspec=None,
|
||||
)
|
||||
]
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
|
||||
codebuild_client,
|
||||
):
|
||||
from prowler.providers.aws.services.codebuild.codebuild_project_older_90_days.codebuild_project_older_90_days import (
|
||||
codebuild_project_older_90_days,
|
||||
)
|
||||
|
||||
check = codebuild_project_older_90_days()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"has been invoked in the last 90 days", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
assert result[0].resource_arn == ""
|
||||
@@ -0,0 +1,123 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.codebuild.codebuild_service import CodebuildProject
|
||||
|
||||
|
||||
class Test_codebuild_project_user_controlled_buildspec:
|
||||
def test_project_not_buildspec(self):
|
||||
codebuild_client = mock.MagicMock
|
||||
codebuild_client.projects = [
|
||||
CodebuildProject(
|
||||
name="test",
|
||||
region="eu-west-1",
|
||||
last_invoked_time=None,
|
||||
buildspec=None,
|
||||
)
|
||||
]
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
|
||||
codebuild_client,
|
||||
):
|
||||
from prowler.providers.aws.services.codebuild.codebuild_project_user_controlled_buildspec.codebuild_project_user_controlled_buildspec import (
|
||||
codebuild_project_user_controlled_buildspec,
|
||||
)
|
||||
|
||||
check = codebuild_project_user_controlled_buildspec()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"does not use a user controlled buildspec",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
assert result[0].resource_arn == ""
|
||||
|
||||
def test_project_buildspec_not_yaml(self):
|
||||
codebuild_client = mock.MagicMock
|
||||
codebuild_client.projects = [
|
||||
CodebuildProject(
|
||||
name="test",
|
||||
region="eu-west-1",
|
||||
last_invoked_time=None,
|
||||
buildspec="arn:aws:s3:::my-codebuild-sample2/buildspec.out",
|
||||
)
|
||||
]
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
|
||||
codebuild_client,
|
||||
):
|
||||
from prowler.providers.aws.services.codebuild.codebuild_project_user_controlled_buildspec.codebuild_project_user_controlled_buildspec import (
|
||||
codebuild_project_user_controlled_buildspec,
|
||||
)
|
||||
|
||||
check = codebuild_project_user_controlled_buildspec()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"does not use a user controlled buildspec",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
assert result[0].resource_arn == ""
|
||||
|
||||
def test_project_valid_buildspec(self):
|
||||
codebuild_client = mock.MagicMock
|
||||
codebuild_client.projects = [
|
||||
CodebuildProject(
|
||||
name="test",
|
||||
region="eu-west-1",
|
||||
last_invoked_time=None,
|
||||
buildspec="arn:aws:s3:::my-codebuild-sample2/buildspec.yaml",
|
||||
)
|
||||
]
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
|
||||
codebuild_client,
|
||||
):
|
||||
from prowler.providers.aws.services.codebuild.codebuild_project_user_controlled_buildspec.codebuild_project_user_controlled_buildspec import (
|
||||
codebuild_project_user_controlled_buildspec,
|
||||
)
|
||||
|
||||
check = codebuild_project_user_controlled_buildspec()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search("uses a user controlled buildspec", result[0].status_extended)
|
||||
assert result[0].resource_id == "test"
|
||||
assert result[0].resource_arn == ""
|
||||
|
||||
def test_project_invalid_buildspec_without_extension(self):
|
||||
codebuild_client = mock.MagicMock
|
||||
codebuild_client.projects = [
|
||||
CodebuildProject(
|
||||
name="test",
|
||||
region="eu-west-1",
|
||||
last_invoked_time=None,
|
||||
buildspec="arn:aws:s3:::my-codebuild-sample2/buildspecyaml",
|
||||
)
|
||||
]
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.codebuild.codebuild_service.Codebuild",
|
||||
codebuild_client,
|
||||
):
|
||||
from prowler.providers.aws.services.codebuild.codebuild_project_user_controlled_buildspec.codebuild_project_user_controlled_buildspec import (
|
||||
codebuild_project_user_controlled_buildspec,
|
||||
)
|
||||
|
||||
check = codebuild_project_user_controlled_buildspec()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"does not use a user controlled buildspec",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "test"
|
||||
assert result[0].resource_arn == ""
|
||||
101
tests/providers/aws/services/codebuild/codebuild_service_test.py
Normal file
101
tests/providers/aws/services/codebuild/codebuild_service_test.py
Normal file
@@ -0,0 +1,101 @@
|
||||
from datetime import datetime, timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
import botocore
|
||||
from boto3 import session
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
|
||||
# last time invoked time
|
||||
last_invoked_time = datetime.now() - timedelta(days=2)
|
||||
|
||||
|
||||
# Mocking batch_get_projects
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
if operation_name == "ListProjects":
|
||||
return {"projects": ["test"]}
|
||||
if operation_name == "ListBuildsForProject":
|
||||
return {"ids": ["test:93f838a7-cd20-48ae-90e5-c10fbbc78ca6"]}
|
||||
if operation_name == "BatchGetBuilds":
|
||||
return {"builds": [{"endTime": last_invoked_time}]}
|
||||
if operation_name == "BatchGetProjects":
|
||||
return {
|
||||
"projects": [
|
||||
{
|
||||
"source": {
|
||||
"buildspec": "arn:aws:s3:::my-codebuild-sample2/buildspec.yml"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
# Mock generate_regional_clients()
|
||||
def mock_generate_regional_clients(service, audit_info):
|
||||
regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION)
|
||||
regional_client.region = AWS_REGION
|
||||
return {AWS_REGION: regional_client}
|
||||
|
||||
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
@patch(
|
||||
"prowler.providers.aws.services.codebuild.codebuild_service.generate_regional_clients",
|
||||
new=mock_generate_regional_clients,
|
||||
)
|
||||
class Test_Codebuild_Service:
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test Codebuild Session
|
||||
def test__get_session__(self):
|
||||
codebuild = Codebuild(current_audit_info)
|
||||
assert codebuild.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test Codebuild Service
|
||||
def test__get_service__(self):
|
||||
codebuild = Codebuild(current_audit_info)
|
||||
assert codebuild.service == "codebuild"
|
||||
|
||||
def test__list_projects__(self):
|
||||
codebuild = Codebuild(current_audit_info)
|
||||
assert len(codebuild.projects) == 1
|
||||
assert codebuild.projects[0].name == "test"
|
||||
assert codebuild.projects[0].region == AWS_REGION
|
||||
|
||||
def test__list_builds_for_project__(self):
|
||||
codebuild = Codebuild(current_audit_info)
|
||||
assert len(codebuild.projects) == 1
|
||||
assert codebuild.projects[0].name == "test"
|
||||
assert codebuild.projects[0].region == AWS_REGION
|
||||
assert codebuild.projects[0].last_invoked_time == last_invoked_time
|
||||
assert (
|
||||
codebuild.projects[0].buildspec
|
||||
== "arn:aws:s3:::my-codebuild-sample2/buildspec.yml"
|
||||
)
|
||||
@@ -0,0 +1,107 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_config
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_config_recorder_all_regions_enabled:
|
||||
@mock_config
|
||||
def test_config_no_recorders(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.config.config_service import Config
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.config.config_recorder_all_regions_enabled.config_recorder_all_regions_enabled.config_client",
|
||||
new=Config(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.config.config_recorder_all_regions_enabled.config_recorder_all_regions_enabled import (
|
||||
config_recorder_all_regions_enabled,
|
||||
)
|
||||
|
||||
check = config_recorder_all_regions_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert (
|
||||
len(result) == 25
|
||||
) # One fail result per region, since there are no recorders
|
||||
assert result[0].status == "FAIL"
|
||||
|
||||
@mock_config
|
||||
def test_config_one_recoder_disabled(self):
|
||||
# Create Config Mocked Resources
|
||||
config_client = client("config", region_name=AWS_REGION)
|
||||
# Create Config Recorder
|
||||
config_client.put_configuration_recorder(
|
||||
ConfigurationRecorder={"name": "default", "roleARN": "somearn"}
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.config.config_service import Config
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.config.config_recorder_all_regions_enabled.config_recorder_all_regions_enabled.config_client",
|
||||
new=Config(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.config.config_recorder_all_regions_enabled.config_recorder_all_regions_enabled import (
|
||||
config_recorder_all_regions_enabled,
|
||||
)
|
||||
|
||||
check = config_recorder_all_regions_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 25
|
||||
# Search for the recorder just created
|
||||
for recorder in result:
|
||||
if recorder.resource_id:
|
||||
assert recorder.status == "FAIL"
|
||||
assert (
|
||||
recorder.status_extended
|
||||
== "AWS Config recorder default is disabled."
|
||||
)
|
||||
assert recorder.resource_id == "default"
|
||||
|
||||
@mock_config
|
||||
def test_config_one_recoder_enabled(self):
|
||||
# Create Config Mocked Resources
|
||||
config_client = client("config", region_name=AWS_REGION)
|
||||
# Create Config Recorder and start it
|
||||
config_client.put_configuration_recorder(
|
||||
ConfigurationRecorder={"name": "default", "roleARN": "somearn"}
|
||||
)
|
||||
# Make the delivery channel
|
||||
config_client.put_delivery_channel(
|
||||
DeliveryChannel={"name": "testchannel", "s3BucketName": "somebucket"}
|
||||
)
|
||||
config_client.start_configuration_recorder(ConfigurationRecorderName="default")
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.config.config_service import Config
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.config.config_recorder_all_regions_enabled.config_recorder_all_regions_enabled.config_client",
|
||||
new=Config(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.config.config_recorder_all_regions_enabled.config_recorder_all_regions_enabled import (
|
||||
config_recorder_all_regions_enabled,
|
||||
)
|
||||
|
||||
check = config_recorder_all_regions_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 25
|
||||
# Search for the recorder just created
|
||||
for recorder in result:
|
||||
if recorder.resource_id:
|
||||
assert recorder.status == "PASS"
|
||||
assert (
|
||||
recorder.status_extended
|
||||
== "AWS Config recorder default is enabled."
|
||||
)
|
||||
assert recorder.resource_id == "default"
|
||||
89
tests/providers/aws/services/config/config_service_test.py
Normal file
89
tests/providers/aws/services/config/config_service_test.py
Normal file
@@ -0,0 +1,89 @@
|
||||
from boto3 import client, session
|
||||
from moto import mock_config
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.config.config_service import Config
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_Config_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test Config Service
|
||||
@mock_config
|
||||
def test_service(self):
|
||||
# Config client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
config = Config(audit_info)
|
||||
assert config.service == "config"
|
||||
|
||||
# Test Config Client
|
||||
@mock_config
|
||||
def test_client(self):
|
||||
# Config client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
config = Config(audit_info)
|
||||
for regional_client in config.regional_clients.values():
|
||||
assert regional_client.__class__.__name__ == "ConfigService"
|
||||
|
||||
# Test Config Session
|
||||
@mock_config
|
||||
def test__get_session__(self):
|
||||
# Config client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
config = Config(audit_info)
|
||||
assert config.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test Config Session
|
||||
@mock_config
|
||||
def test_audited_account(self):
|
||||
# Config client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
config = Config(audit_info)
|
||||
assert config.audited_account == AWS_ACCOUNT_NUMBER
|
||||
|
||||
# Test Config Get Rest APIs
|
||||
@mock_config
|
||||
def test__describe_configuration_recorder_status__(self):
|
||||
# Generate Config Client
|
||||
config_client = client("config", region_name=AWS_REGION)
|
||||
# Create Config Recorder and start it
|
||||
config_client.put_configuration_recorder(
|
||||
ConfigurationRecorder={"name": "default", "roleARN": "somearn"}
|
||||
)
|
||||
# Make the delivery channel
|
||||
config_client.put_delivery_channel(
|
||||
DeliveryChannel={"name": "testchannel", "s3BucketName": "somebucket"}
|
||||
)
|
||||
config_client.start_configuration_recorder(ConfigurationRecorderName="default")
|
||||
# Config client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
config = Config(audit_info)
|
||||
# One recorder per region
|
||||
assert len(config.recorders) == 25
|
||||
# Check the active one
|
||||
# Search for the recorder just created
|
||||
for recorder in config.recorders:
|
||||
if recorder.name == "default":
|
||||
assert recorder.recording is True
|
||||
@@ -0,0 +1,103 @@
|
||||
from datetime import datetime
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_service import (
|
||||
Directory,
|
||||
DirectoryType,
|
||||
LogSubscriptions,
|
||||
)
|
||||
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_directoryservice_directory_log_forwarding_enabled:
|
||||
def test_no_directories(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directoryservice_client.directories = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_log_forwarding_enabled.directoryservice_directory_log_forwarding_enabled import (
|
||||
directoryservice_directory_log_forwarding_enabled,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_log_forwarding_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_directory_logging_disabled(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
log_subscriptions=[],
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_log_forwarding_enabled.directoryservice_directory_log_forwarding_enabled import (
|
||||
directoryservice_directory_log_forwarding_enabled,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_log_forwarding_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory Service {directory_id} have log forwarding to CloudWatch disabled"
|
||||
)
|
||||
|
||||
def test_one_directory_logging_enabled(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
log_subscriptions=[
|
||||
LogSubscriptions(
|
||||
log_group_name="test-log-group",
|
||||
created_date_time=datetime(2022, 1, 1),
|
||||
)
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_log_forwarding_enabled.directoryservice_directory_log_forwarding_enabled import (
|
||||
directoryservice_directory_log_forwarding_enabled,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_log_forwarding_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory Service {directory_id} have log forwarding to CloudWatch enabled"
|
||||
)
|
||||
@@ -0,0 +1,107 @@
|
||||
from datetime import datetime
|
||||
from unittest import mock
|
||||
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_service import (
|
||||
Directory,
|
||||
DirectoryType,
|
||||
EventTopics,
|
||||
EventTopicStatus,
|
||||
)
|
||||
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_directoryservice_directory_monitor_notifications:
|
||||
def test_no_directories(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directoryservice_client.directories = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_monitor_notifications.directoryservice_directory_monitor_notifications import (
|
||||
directoryservice_directory_monitor_notifications,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_monitor_notifications()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_directory_logging_disabled(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
name=directory_name,
|
||||
region=AWS_REGION,
|
||||
event_topics=[],
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_monitor_notifications.directoryservice_directory_monitor_notifications import (
|
||||
directoryservice_directory_monitor_notifications,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_monitor_notifications()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory Service {directory_id} have SNS messaging disabled"
|
||||
)
|
||||
|
||||
def test_one_directory_logging_enabled(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
event_topics=[
|
||||
EventTopics(
|
||||
topic_arn=f"arn:aws:sns:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:test-topic",
|
||||
topic_name="test-topic",
|
||||
status=EventTopicStatus.Registered,
|
||||
created_date_time=datetime(2022, 1, 1),
|
||||
)
|
||||
],
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_monitor_notifications.directoryservice_directory_monitor_notifications import (
|
||||
directoryservice_directory_monitor_notifications,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_monitor_notifications()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory Service {directory_id} have SNS messaging enabled"
|
||||
)
|
||||
@@ -0,0 +1,192 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_service import (
|
||||
Directory,
|
||||
DirectoryType,
|
||||
SnapshotLimit,
|
||||
)
|
||||
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_directoryservice_directory_snapshots_limit:
|
||||
def test_no_directories(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directoryservice_client.directories = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_snapshots_limit.directoryservice_directory_snapshots_limit import (
|
||||
directoryservice_directory_snapshots_limit,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_snapshots_limit()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_directory_snapshots_limit_reached(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
manual_snapshots_current_count = 5
|
||||
manual_snapshots_limit = 5
|
||||
manual_snapshots_limit_reached = True
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
snapshots_limits=SnapshotLimit(
|
||||
manual_snapshots_current_count=manual_snapshots_current_count,
|
||||
manual_snapshots_limit=manual_snapshots_limit,
|
||||
manual_snapshots_limit_reached=manual_snapshots_limit_reached,
|
||||
),
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_snapshots_limit.directoryservice_directory_snapshots_limit import (
|
||||
directoryservice_directory_snapshots_limit,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_snapshots_limit()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory Service {directory_id} reached {manual_snapshots_limit} Snapshots limit"
|
||||
)
|
||||
|
||||
def test_one_directory_snapshots_limit_over_threshold(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
manual_snapshots_current_count = 4
|
||||
manual_snapshots_limit = 5
|
||||
manual_snapshots_limit_reached = False
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
snapshots_limits=SnapshotLimit(
|
||||
manual_snapshots_current_count=manual_snapshots_current_count,
|
||||
manual_snapshots_limit=manual_snapshots_limit,
|
||||
manual_snapshots_limit_reached=manual_snapshots_limit_reached,
|
||||
),
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_snapshots_limit.directoryservice_directory_snapshots_limit import (
|
||||
directoryservice_directory_snapshots_limit,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_snapshots_limit()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory Service {directory_id} is about to reach {manual_snapshots_limit} Snapshots which is the limit"
|
||||
)
|
||||
|
||||
def test_one_directory_snapshots_limit_equal_threshold(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
manual_snapshots_current_count = 3
|
||||
manual_snapshots_limit = 5
|
||||
manual_snapshots_limit_reached = False
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
snapshots_limits=SnapshotLimit(
|
||||
manual_snapshots_current_count=manual_snapshots_current_count,
|
||||
manual_snapshots_limit=manual_snapshots_limit,
|
||||
manual_snapshots_limit_reached=manual_snapshots_limit_reached,
|
||||
),
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_snapshots_limit.directoryservice_directory_snapshots_limit import (
|
||||
directoryservice_directory_snapshots_limit,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_snapshots_limit()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory Service {directory_id} is about to reach {manual_snapshots_limit} Snapshots which is the limit"
|
||||
)
|
||||
|
||||
def test_one_directory_snapshots_limit_more_threshold(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
manual_snapshots_current_count = 1
|
||||
manual_snapshots_limit = 5
|
||||
manual_snapshots_limit_reached = False
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
snapshots_limits=SnapshotLimit(
|
||||
manual_snapshots_current_count=manual_snapshots_current_count,
|
||||
manual_snapshots_limit=manual_snapshots_limit,
|
||||
manual_snapshots_limit_reached=manual_snapshots_limit_reached,
|
||||
),
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_directory_snapshots_limit.directoryservice_directory_snapshots_limit import (
|
||||
directoryservice_directory_snapshots_limit,
|
||||
)
|
||||
|
||||
check = directoryservice_directory_snapshots_limit()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory Service {directory_id} is using {manual_snapshots_current_count} out of {manual_snapshots_limit} from the Snapshots Limit"
|
||||
)
|
||||
@@ -0,0 +1,200 @@
|
||||
from datetime import datetime
|
||||
from unittest import mock
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_service import (
|
||||
Certificate,
|
||||
CertificateState,
|
||||
CertificateType,
|
||||
Directory,
|
||||
DirectoryType,
|
||||
)
|
||||
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
# Always use a mocked date to test the certificates expiration
|
||||
@freeze_time("2023-01-01")
|
||||
class Test_directoryservice_ldap_certificate_expiration:
|
||||
def test_no_directories(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directoryservice_client.directories = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_ldap_certificate_expiration.directoryservice_ldap_certificate_expiration import (
|
||||
directoryservice_ldap_certificate_expiration,
|
||||
)
|
||||
|
||||
check = directoryservice_ldap_certificate_expiration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_directory_no_certificate(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
name=directory_name,
|
||||
region=AWS_REGION,
|
||||
certificates=[],
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_ldap_certificate_expiration.directoryservice_ldap_certificate_expiration import (
|
||||
directoryservice_ldap_certificate_expiration,
|
||||
)
|
||||
|
||||
check = directoryservice_ldap_certificate_expiration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_directory_certificate_expires_in_365_days(self):
|
||||
remaining_days_to_expire = 365
|
||||
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
certificate_id = "test-certificate"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
certificates=[
|
||||
Certificate(
|
||||
id=certificate_id,
|
||||
common_name=certificate_id,
|
||||
state=CertificateState.Registered,
|
||||
type=CertificateType.ClientLDAPS,
|
||||
expiry_date_time=datetime(2024, 1, 1),
|
||||
)
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_ldap_certificate_expiration.directoryservice_ldap_certificate_expiration import (
|
||||
directoryservice_ldap_certificate_expiration,
|
||||
)
|
||||
|
||||
check = directoryservice_ldap_certificate_expiration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == certificate_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"LDAP Certificate {certificate_id} configured at {directory_id} expires in {remaining_days_to_expire} days"
|
||||
)
|
||||
|
||||
def test_directory_certificate_expires_in_90_days(self):
|
||||
remaining_days_to_expire = 90
|
||||
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
certificate_id = "test-certificate"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
certificates=[
|
||||
Certificate(
|
||||
id=certificate_id,
|
||||
common_name=certificate_id,
|
||||
state=CertificateState.Registered,
|
||||
type=CertificateType.ClientLDAPS,
|
||||
expiry_date_time=datetime(2023, 4, 1),
|
||||
)
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_ldap_certificate_expiration.directoryservice_ldap_certificate_expiration import (
|
||||
directoryservice_ldap_certificate_expiration,
|
||||
)
|
||||
|
||||
check = directoryservice_ldap_certificate_expiration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == certificate_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"LDAP Certificate {certificate_id} configured at {directory_id} is about to expire in {remaining_days_to_expire} days"
|
||||
)
|
||||
|
||||
def test_directory_certificate_expires_in_31_days(self):
|
||||
remaining_days_to_expire = 31
|
||||
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
certificate_id = "test-certificate"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
certificates=[
|
||||
Certificate(
|
||||
id=certificate_id,
|
||||
common_name=certificate_id,
|
||||
state=CertificateState.Registered,
|
||||
type=CertificateType.ClientLDAPS,
|
||||
expiry_date_time=datetime(2023, 2, 1),
|
||||
)
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_ldap_certificate_expiration.directoryservice_ldap_certificate_expiration import (
|
||||
directoryservice_ldap_certificate_expiration,
|
||||
)
|
||||
|
||||
check = directoryservice_ldap_certificate_expiration()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == certificate_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"LDAP Certificate {certificate_id} configured at {directory_id} is about to expire in {remaining_days_to_expire} days"
|
||||
)
|
||||
@@ -0,0 +1,131 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_service import (
|
||||
AuthenticationProtocol,
|
||||
Directory,
|
||||
DirectoryType,
|
||||
RadiusSettings,
|
||||
RadiusStatus,
|
||||
)
|
||||
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_directoryservice_radius_server_security_protocol:
|
||||
def test_no_directories(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directoryservice_client.directories = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_radius_server_security_protocol.directoryservice_radius_server_security_protocol import (
|
||||
directoryservice_radius_server_security_protocol,
|
||||
)
|
||||
|
||||
check = directoryservice_radius_server_security_protocol()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_directory_no_radius_server(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
radius_settings=None,
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_radius_server_security_protocol.directoryservice_radius_server_security_protocol import (
|
||||
directoryservice_radius_server_security_protocol,
|
||||
)
|
||||
|
||||
check = directoryservice_radius_server_security_protocol()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_directory_radius_server_bad_auth_protocol(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
radius_settings=RadiusSettings(
|
||||
authentication_protocol=AuthenticationProtocol.MS_CHAPv1,
|
||||
status=RadiusStatus.Completed,
|
||||
),
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_radius_server_security_protocol.directoryservice_radius_server_security_protocol import (
|
||||
directoryservice_radius_server_security_protocol,
|
||||
)
|
||||
|
||||
check = directoryservice_radius_server_security_protocol()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Radius server of Directory {directory_id} does not have recommended security protocol for the Radius server"
|
||||
)
|
||||
|
||||
def test_directory_radius_server_secure_auth_protocol(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
radius_settings=RadiusSettings(
|
||||
authentication_protocol=AuthenticationProtocol.MS_CHAPv2,
|
||||
status=RadiusStatus.Completed,
|
||||
),
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_radius_server_security_protocol.directoryservice_radius_server_security_protocol import (
|
||||
directoryservice_radius_server_security_protocol,
|
||||
)
|
||||
|
||||
check = directoryservice_radius_server_security_protocol()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Radius server of Directory {directory_id} have recommended security protocol for the Radius server"
|
||||
)
|
||||
@@ -0,0 +1,230 @@
|
||||
from datetime import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
import botocore
|
||||
from moto import mock_ds
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_service import (
|
||||
AuthenticationProtocol,
|
||||
CertificateState,
|
||||
CertificateType,
|
||||
DirectoryService,
|
||||
DirectoryType,
|
||||
EventTopicStatus,
|
||||
RadiusStatus,
|
||||
)
|
||||
|
||||
# Mock Test Region
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
# Mocking Access Analyzer Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
|
||||
def mock_make_api_call(self, operation_name, kwarg):
|
||||
"""We have to mock every AWS API call using Boto3"""
|
||||
if operation_name == "DescribeDirectories":
|
||||
return {
|
||||
"DirectoryDescriptions": [
|
||||
{
|
||||
"DirectoryId": "d-12345a1b2",
|
||||
"Name": "test-directory",
|
||||
"Type": "MicrosoftAD",
|
||||
"ShortName": "test-directory",
|
||||
"RadiusSettings": {
|
||||
"RadiusServers": [
|
||||
"test-server",
|
||||
],
|
||||
"RadiusPort": 9999,
|
||||
"RadiusTimeout": 100,
|
||||
"RadiusRetries": 100,
|
||||
"SharedSecret": "test-shared-secret",
|
||||
"AuthenticationProtocol": "MS-CHAPv2",
|
||||
"DisplayLabel": "test-directory",
|
||||
"UseSameUsername": True | False,
|
||||
},
|
||||
"RadiusStatus": "Creating",
|
||||
},
|
||||
],
|
||||
}
|
||||
if operation_name == "ListLogSubscriptions":
|
||||
return {
|
||||
"LogSubscriptions": [
|
||||
{
|
||||
"DirectoryId": "d-12345a1b2",
|
||||
"LogGroupName": "test-log-group",
|
||||
"SubscriptionCreatedDateTime": datetime(2022, 1, 1),
|
||||
},
|
||||
],
|
||||
}
|
||||
if operation_name == "DescribeEventTopics":
|
||||
return {
|
||||
"EventTopics": [
|
||||
{
|
||||
"DirectoryId": "d-12345a1b2",
|
||||
"TopicName": "test-topic",
|
||||
"TopicArn": f"arn:aws:sns:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:test-topic",
|
||||
"CreatedDateTime": datetime(2022, 1, 1),
|
||||
"Status": "Registered",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
if operation_name == "ListCertificates":
|
||||
return {
|
||||
"CertificatesInfo": [
|
||||
{
|
||||
"CertificateId": "test-certificate",
|
||||
"CommonName": "test-certificate",
|
||||
"State": "Registered",
|
||||
"ExpiryDateTime": datetime(2023, 1, 1),
|
||||
"Type": "ClientLDAPS",
|
||||
},
|
||||
]
|
||||
}
|
||||
if operation_name == "GetSnapshotLimits":
|
||||
return {
|
||||
"SnapshotLimits": {
|
||||
"ManualSnapshotsLimit": 123,
|
||||
"ManualSnapshotsCurrentCount": 123,
|
||||
"ManualSnapshotsLimitReached": True,
|
||||
}
|
||||
}
|
||||
|
||||
return make_api_call(self, operation_name, kwarg)
|
||||
|
||||
|
||||
# Mock generate_regional_clients()
|
||||
def mock_generate_regional_clients(service, audit_info):
|
||||
regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION)
|
||||
regional_client.region = AWS_REGION
|
||||
return {AWS_REGION: regional_client}
|
||||
|
||||
|
||||
# Patch every AWS call using Boto3 and generate_regional_clients to have 1 client
|
||||
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
|
||||
@patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.generate_regional_clients",
|
||||
new=mock_generate_regional_clients,
|
||||
)
|
||||
class Test_DirectoryService_Service:
|
||||
# Test DirectoryService Client
|
||||
@mock_ds
|
||||
def test__get_client__(self):
|
||||
directoryservice = DirectoryService(current_audit_info)
|
||||
assert (
|
||||
directoryservice.regional_clients[AWS_REGION].__class__.__name__
|
||||
== "DirectoryService"
|
||||
)
|
||||
|
||||
# Test DirectoryService Session
|
||||
@mock_ds
|
||||
def test__get_session__(self):
|
||||
directoryservice = DirectoryService(current_audit_info)
|
||||
assert directoryservice.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test DirectoryService Service
|
||||
@mock_ds
|
||||
def test__get_service__(self):
|
||||
directoryservice = DirectoryService(current_audit_info)
|
||||
assert directoryservice.service == "ds"
|
||||
|
||||
@mock_ds
|
||||
def test__describe_directories__(self):
|
||||
# Set partition for the service
|
||||
current_audit_info.audited_partition = "aws"
|
||||
directoryservice = DirectoryService(current_audit_info)
|
||||
|
||||
# __describe_directories__
|
||||
assert directoryservice.directories["d-12345a1b2"].id == "d-12345a1b2"
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"].type
|
||||
== DirectoryType.MicrosoftAD
|
||||
)
|
||||
assert directoryservice.directories["d-12345a1b2"].name == "test-directory"
|
||||
assert directoryservice.directories["d-12345a1b2"].region == AWS_REGION
|
||||
assert (
|
||||
directoryservice.directories[
|
||||
"d-12345a1b2"
|
||||
].radius_settings.authentication_protocol
|
||||
== AuthenticationProtocol.MS_CHAPv2
|
||||
)
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"].radius_settings.status
|
||||
== RadiusStatus.Creating
|
||||
)
|
||||
|
||||
# __list_log_subscriptions__
|
||||
assert len(directoryservice.directories["d-12345a1b2"].log_subscriptions) == 1
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"]
|
||||
.log_subscriptions[0]
|
||||
.log_group_name
|
||||
== "test-log-group"
|
||||
)
|
||||
assert directoryservice.directories["d-12345a1b2"].log_subscriptions[
|
||||
0
|
||||
].created_date_time == datetime(2022, 1, 1)
|
||||
|
||||
# __describe_event_topics__
|
||||
assert len(directoryservice.directories["d-12345a1b2"].event_topics) == 1
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"].event_topics[0].topic_name
|
||||
== "test-topic"
|
||||
)
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"].event_topics[0].topic_arn
|
||||
== f"arn:aws:sns:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:test-topic"
|
||||
)
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"].event_topics[0].status
|
||||
== EventTopicStatus.Registered
|
||||
)
|
||||
assert directoryservice.directories["d-12345a1b2"].event_topics[
|
||||
0
|
||||
].created_date_time == datetime(2022, 1, 1)
|
||||
|
||||
# __list_certificates__
|
||||
assert len(directoryservice.directories["d-12345a1b2"].certificates) == 1
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"].certificates[0].id
|
||||
== "test-certificate"
|
||||
)
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"].certificates[0].common_name
|
||||
== "test-certificate"
|
||||
)
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"].certificates[0].state
|
||||
== CertificateState.Registered
|
||||
)
|
||||
assert directoryservice.directories["d-12345a1b2"].certificates[
|
||||
0
|
||||
].expiry_date_time == datetime(2023, 1, 1)
|
||||
assert (
|
||||
directoryservice.directories["d-12345a1b2"].certificates[0].type
|
||||
== CertificateType.ClientLDAPS
|
||||
)
|
||||
|
||||
# __get_snapshot_limits__
|
||||
assert directoryservice.directories["d-12345a1b2"].snapshots_limits
|
||||
assert (
|
||||
directoryservice.directories[
|
||||
"d-12345a1b2"
|
||||
].snapshots_limits.manual_snapshots_limit
|
||||
== 123
|
||||
)
|
||||
assert (
|
||||
directoryservice.directories[
|
||||
"d-12345a1b2"
|
||||
].snapshots_limits.manual_snapshots_current_count
|
||||
== 123
|
||||
)
|
||||
assert (
|
||||
directoryservice.directories[
|
||||
"d-12345a1b2"
|
||||
].snapshots_limits.manual_snapshots_limit_reached
|
||||
is True
|
||||
)
|
||||
@@ -0,0 +1,168 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_service import (
|
||||
AuthenticationProtocol,
|
||||
Directory,
|
||||
DirectoryType,
|
||||
RadiusSettings,
|
||||
RadiusStatus,
|
||||
)
|
||||
|
||||
AWS_REGION = "eu-west-1"
|
||||
|
||||
|
||||
class Test_directoryservice_supported_mfa_radius_enabled:
|
||||
def test_no_directories(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directoryservice_client.directories = {}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_supported_mfa_radius_enabled.directoryservice_supported_mfa_radius_enabled import (
|
||||
directoryservice_supported_mfa_radius_enabled,
|
||||
)
|
||||
|
||||
check = directoryservice_supported_mfa_radius_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_directory_no_radius_server(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
radius_settings=None,
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_supported_mfa_radius_enabled.directoryservice_supported_mfa_radius_enabled import (
|
||||
directoryservice_supported_mfa_radius_enabled,
|
||||
)
|
||||
|
||||
check = directoryservice_supported_mfa_radius_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
def test_directory_radius_server_status_failed(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
radius_settings=RadiusSettings(
|
||||
authentication_protocol=AuthenticationProtocol.MS_CHAPv1,
|
||||
status=RadiusStatus.Failed,
|
||||
),
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_supported_mfa_radius_enabled.directoryservice_supported_mfa_radius_enabled import (
|
||||
directoryservice_supported_mfa_radius_enabled,
|
||||
)
|
||||
|
||||
check = directoryservice_supported_mfa_radius_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory {directory_id} does not have Radius MFA enabled"
|
||||
)
|
||||
|
||||
def test_directory_radius_server_status_creating(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
radius_settings=RadiusSettings(
|
||||
authentication_protocol=AuthenticationProtocol.MS_CHAPv2,
|
||||
status=RadiusStatus.Creating,
|
||||
),
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_supported_mfa_radius_enabled.directoryservice_supported_mfa_radius_enabled import (
|
||||
directoryservice_supported_mfa_radius_enabled,
|
||||
)
|
||||
|
||||
check = directoryservice_supported_mfa_radius_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory {directory_id} does not have Radius MFA enabled"
|
||||
)
|
||||
|
||||
def test_directory_radius_server_status_completed(self):
|
||||
directoryservice_client = mock.MagicMock
|
||||
directory_name = "test-directory"
|
||||
directory_id = "d-12345a1b2"
|
||||
directoryservice_client.directories = {
|
||||
directory_name: Directory(
|
||||
name=directory_name,
|
||||
id=directory_id,
|
||||
type=DirectoryType.MicrosoftAD,
|
||||
region=AWS_REGION,
|
||||
radius_settings=RadiusSettings(
|
||||
authentication_protocol=AuthenticationProtocol.MS_CHAPv2,
|
||||
status=RadiusStatus.Completed,
|
||||
),
|
||||
)
|
||||
}
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.directoryservice.directoryservice_service.DirectoryService",
|
||||
new=directoryservice_client,
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.directoryservice.directoryservice_supported_mfa_radius_enabled.directoryservice_supported_mfa_radius_enabled import (
|
||||
directoryservice_supported_mfa_radius_enabled,
|
||||
)
|
||||
|
||||
check = directoryservice_supported_mfa_radius_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == directory_id
|
||||
assert result[0].region == AWS_REGION
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Directory {directory_id} have Radius MFA enabled"
|
||||
)
|
||||
@@ -0,0 +1,101 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_dax
|
||||
from moto.core import DEFAULT_ACCOUNT_ID
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_dynamodb_accelerator_cluster_encryption_enabled:
|
||||
@mock_dax
|
||||
def test_dax_no_clusters(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DAX
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.dynamodb.dynamodb_accelerator_cluster_encryption_enabled.dynamodb_accelerator_cluster_encryption_enabled.dax_client",
|
||||
new=DAX(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_accelerator_cluster_encryption_enabled.dynamodb_accelerator_cluster_encryption_enabled import (
|
||||
dynamodb_accelerator_cluster_encryption_enabled,
|
||||
)
|
||||
|
||||
check = dynamodb_accelerator_cluster_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_dax
|
||||
def test_dax_cluster_no_encryption(self):
|
||||
dax_client = client("dax", region_name=AWS_REGION)
|
||||
iam_role_arn = f"arn:aws:iam::{DEFAULT_ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
|
||||
cluster = dax_client.create_cluster(
|
||||
ClusterName="daxcluster",
|
||||
NodeType="dax.t3.small",
|
||||
ReplicationFactor=3,
|
||||
IamRoleArn=iam_role_arn,
|
||||
)["Cluster"]
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DAX
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.dynamodb.dynamodb_accelerator_cluster_encryption_enabled.dynamodb_accelerator_cluster_encryption_enabled.dax_client",
|
||||
new=DAX(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_accelerator_cluster_encryption_enabled.dynamodb_accelerator_cluster_encryption_enabled import (
|
||||
dynamodb_accelerator_cluster_encryption_enabled,
|
||||
)
|
||||
|
||||
check = dynamodb_accelerator_cluster_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"does not have encryption at rest enabled",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == cluster["ClusterName"]
|
||||
assert result[0].resource_arn == cluster["ClusterArn"]
|
||||
|
||||
@mock_dax
|
||||
def test_dax_cluster_with_encryption(self):
|
||||
dax_client = client("dax", region_name=AWS_REGION)
|
||||
iam_role_arn = f"arn:aws:iam::{DEFAULT_ACCOUNT_ID}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
|
||||
cluster = dax_client.create_cluster(
|
||||
ClusterName="daxcluster",
|
||||
NodeType="dax.t3.small",
|
||||
ReplicationFactor=3,
|
||||
IamRoleArn=iam_role_arn,
|
||||
SSESpecification={"Enabled": True},
|
||||
)["Cluster"]
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DAX
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.dynamodb.dynamodb_accelerator_cluster_encryption_enabled.dynamodb_accelerator_cluster_encryption_enabled.dax_client",
|
||||
new=DAX(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_accelerator_cluster_encryption_enabled.dynamodb_accelerator_cluster_encryption_enabled import (
|
||||
dynamodb_accelerator_cluster_encryption_enabled,
|
||||
)
|
||||
|
||||
check = dynamodb_accelerator_cluster_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search("has encryption at rest enabled", result[0].status_extended)
|
||||
assert result[0].resource_id == cluster["ClusterName"]
|
||||
assert result[0].resource_arn == cluster["ClusterArn"]
|
||||
190
tests/providers/aws/services/dynamodb/dynamodb_service_test.py
Normal file
190
tests/providers/aws/services/dynamodb/dynamodb_service_test.py
Normal file
@@ -0,0 +1,190 @@
|
||||
from boto3 import client, session
|
||||
from moto import mock_dax, mock_dynamodb
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DAX, DynamoDB
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_DynamoDB_Service:
|
||||
# Mocked Audit Info
|
||||
def set_mocked_audit_info(self):
|
||||
audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=session.Session(
|
||||
profile_name=None,
|
||||
botocore_session=None,
|
||||
),
|
||||
audited_account=AWS_ACCOUNT_NUMBER,
|
||||
audited_user_id=None,
|
||||
audited_partition="aws",
|
||||
audited_identity_arn=None,
|
||||
profile=None,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=None,
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
return audit_info
|
||||
|
||||
# Test Dynamo Service
|
||||
@mock_dynamodb
|
||||
def test_service(self):
|
||||
# Dynamo client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
dynamodb = DynamoDB(audit_info)
|
||||
assert dynamodb.service == "dynamodb"
|
||||
|
||||
# Test Dynamo Client
|
||||
@mock_dynamodb
|
||||
def test_client(self):
|
||||
# Dynamo client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
dynamodb = DynamoDB(audit_info)
|
||||
for regional_client in dynamodb.regional_clients.values():
|
||||
assert regional_client.__class__.__name__ == "DynamoDB"
|
||||
|
||||
# Test Dynamo Session
|
||||
@mock_dynamodb
|
||||
def test__get_session__(self):
|
||||
# Dynamo client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
dynamodb = DynamoDB(audit_info)
|
||||
assert dynamodb.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test Dynamo Session
|
||||
@mock_dynamodb
|
||||
def test_audited_account(self):
|
||||
# Dynamo client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
dynamodb = DynamoDB(audit_info)
|
||||
assert dynamodb.audited_account == AWS_ACCOUNT_NUMBER
|
||||
|
||||
# Test DynamoDB List Tables
|
||||
@mock_dynamodb
|
||||
def test__list_tables__(self):
|
||||
# Generate DynamoDB Client
|
||||
dynamodb_client = client("dynamodb", region_name=AWS_REGION)
|
||||
# Create DynamoDB Tables
|
||||
dynamodb_client.create_table(
|
||||
TableName="test1",
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "client", "AttributeType": "S"},
|
||||
{"AttributeName": "app", "AttributeType": "S"},
|
||||
],
|
||||
KeySchema=[
|
||||
{"AttributeName": "client", "KeyType": "HASH"},
|
||||
{"AttributeName": "app", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)
|
||||
dynamodb_client.create_table(
|
||||
TableName="test2",
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "client", "AttributeType": "S"},
|
||||
{"AttributeName": "app", "AttributeType": "S"},
|
||||
],
|
||||
KeySchema=[
|
||||
{"AttributeName": "client", "KeyType": "HASH"},
|
||||
{"AttributeName": "app", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)
|
||||
# DynamoDB client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
dynamo = DynamoDB(audit_info)
|
||||
assert len(dynamo.tables) == 2
|
||||
assert dynamo.tables[0].name == "test1"
|
||||
assert dynamo.tables[1].name == "test2"
|
||||
assert dynamo.tables[0].region == AWS_REGION
|
||||
assert dynamo.tables[1].region == AWS_REGION
|
||||
|
||||
# Test DynamoDB Describe Table
|
||||
@mock_dynamodb
|
||||
def test__describe_table__(self):
|
||||
# Generate DynamoDB Client
|
||||
dynamodb_client = client("dynamodb", region_name=AWS_REGION)
|
||||
# Create DynamoDB Table
|
||||
table = dynamodb_client.create_table(
|
||||
TableName="test1",
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "client", "AttributeType": "S"},
|
||||
{"AttributeName": "app", "AttributeType": "S"},
|
||||
],
|
||||
KeySchema=[
|
||||
{"AttributeName": "client", "KeyType": "HASH"},
|
||||
{"AttributeName": "app", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)["TableDescription"]
|
||||
# DynamoDB client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
dynamo = DynamoDB(audit_info)
|
||||
assert len(dynamo.tables) == 1
|
||||
assert dynamo.tables[0].arn == table["TableArn"]
|
||||
assert dynamo.tables[0].name == "test1"
|
||||
assert dynamo.tables[0].region == AWS_REGION
|
||||
|
||||
# Test DynamoDB Describe Table
|
||||
@mock_dynamodb
|
||||
def test__describe_continuous_backups__(self):
|
||||
# Generate DynamoDB Client
|
||||
dynamodb_client = client("dynamodb", region_name=AWS_REGION)
|
||||
# Create DynamoDB Table
|
||||
table = dynamodb_client.create_table(
|
||||
TableName="test1",
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "client", "AttributeType": "S"},
|
||||
{"AttributeName": "app", "AttributeType": "S"},
|
||||
],
|
||||
KeySchema=[
|
||||
{"AttributeName": "client", "KeyType": "HASH"},
|
||||
{"AttributeName": "app", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)["TableDescription"]
|
||||
dynamodb_client.update_continuous_backups(
|
||||
TableName="test1",
|
||||
PointInTimeRecoverySpecification={"PointInTimeRecoveryEnabled": True},
|
||||
)
|
||||
# DynamoDB client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
dynamo = DynamoDB(audit_info)
|
||||
assert len(dynamo.tables) == 1
|
||||
assert dynamo.tables[0].arn == table["TableArn"]
|
||||
assert dynamo.tables[0].name == "test1"
|
||||
assert dynamo.tables[0].pitr
|
||||
assert dynamo.tables[0].region == AWS_REGION
|
||||
|
||||
# Test DAX List Tables
|
||||
@mock_dax
|
||||
def test__describe_clusters__(self):
|
||||
# Generate DAX Client
|
||||
dax_client = client("dax", region_name=AWS_REGION)
|
||||
# Create DAX Clusters
|
||||
iam_role_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:role/aws-service-role/dax.amazonaws.com/AWSServiceRoleForDAX"
|
||||
dax_client.create_cluster(
|
||||
ClusterName="daxcluster1",
|
||||
NodeType="dax.t3.small",
|
||||
ReplicationFactor=3,
|
||||
IamRoleArn=iam_role_arn,
|
||||
SSESpecification={"Enabled": True},
|
||||
)
|
||||
dax_client.create_cluster(
|
||||
ClusterName="daxcluster2",
|
||||
NodeType="dax.t3.small",
|
||||
ReplicationFactor=3,
|
||||
IamRoleArn=iam_role_arn,
|
||||
SSESpecification={"Enabled": True},
|
||||
)
|
||||
# DAX client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
dax = DAX(audit_info)
|
||||
assert len(dax.clusters) == 2
|
||||
assert dax.clusters[0].name == "daxcluster1"
|
||||
assert dax.clusters[1].name == "daxcluster2"
|
||||
assert dax.clusters[0].region == AWS_REGION
|
||||
assert dax.clusters[1].region == AWS_REGION
|
||||
@@ -0,0 +1,107 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_dynamodb
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_dynamodb_tables_kms_cmk_encryption_enabled:
|
||||
@mock_dynamodb
|
||||
def test_dynamodb_no_tables(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DynamoDB
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.dynamodb.dynamodb_tables_kms_cmk_encryption_enabled.dynamodb_tables_kms_cmk_encryption_enabled.dynamodb_client",
|
||||
new=DynamoDB(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_tables_kms_cmk_encryption_enabled.dynamodb_tables_kms_cmk_encryption_enabled import (
|
||||
dynamodb_tables_kms_cmk_encryption_enabled,
|
||||
)
|
||||
|
||||
check = dynamodb_tables_kms_cmk_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_dynamodb
|
||||
def test_dynamodb_table_kms_encryption(self):
|
||||
dynamodb_client = client("dynamodb", region_name=AWS_REGION)
|
||||
table = dynamodb_client.create_table(
|
||||
TableName="test1",
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "client", "AttributeType": "S"},
|
||||
{"AttributeName": "app", "AttributeType": "S"},
|
||||
],
|
||||
KeySchema=[
|
||||
{"AttributeName": "client", "KeyType": "HASH"},
|
||||
{"AttributeName": "app", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
SSESpecification={"Enabled": True, "KMSMasterKeyId": "/custom-kms-key"},
|
||||
)["TableDescription"]
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DynamoDB
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.dynamodb.dynamodb_tables_kms_cmk_encryption_enabled.dynamodb_tables_kms_cmk_encryption_enabled.dynamodb_client",
|
||||
new=DynamoDB(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_tables_kms_cmk_encryption_enabled.dynamodb_tables_kms_cmk_encryption_enabled import (
|
||||
dynamodb_tables_kms_cmk_encryption_enabled,
|
||||
)
|
||||
|
||||
check = dynamodb_tables_kms_cmk_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search("KMS encryption enabled", result[0].status_extended)
|
||||
assert result[0].resource_id == table["TableName"]
|
||||
assert result[0].resource_arn == table["TableArn"]
|
||||
|
||||
@mock_dynamodb
|
||||
def test_dynamodb_table_default_encryption(self):
|
||||
dynamodb_client = client("dynamodb", region_name=AWS_REGION)
|
||||
table = dynamodb_client.create_table(
|
||||
TableName="test1",
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "client", "AttributeType": "S"},
|
||||
{"AttributeName": "app", "AttributeType": "S"},
|
||||
],
|
||||
KeySchema=[
|
||||
{"AttributeName": "client", "KeyType": "HASH"},
|
||||
{"AttributeName": "app", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)["TableDescription"]
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DynamoDB
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.dynamodb.dynamodb_tables_kms_cmk_encryption_enabled.dynamodb_tables_kms_cmk_encryption_enabled.dynamodb_client",
|
||||
new=DynamoDB(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_tables_kms_cmk_encryption_enabled.dynamodb_tables_kms_cmk_encryption_enabled import (
|
||||
dynamodb_tables_kms_cmk_encryption_enabled,
|
||||
)
|
||||
|
||||
check = dynamodb_tables_kms_cmk_encryption_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search("DEFAULT encryption enabled", result[0].status_extended)
|
||||
assert result[0].resource_id == table["TableName"]
|
||||
assert result[0].resource_arn == table["TableArn"]
|
||||
@@ -0,0 +1,115 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_dynamodb
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_dynamodb_tables_pitr_enabled:
|
||||
@mock_dynamodb
|
||||
def test_dynamodb_no_tables(self):
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DynamoDB
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.dynamodb.dynamodb_tables_pitr_enabled.dynamodb_tables_pitr_enabled.dynamodb_client",
|
||||
new=DynamoDB(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_tables_pitr_enabled.dynamodb_tables_pitr_enabled import (
|
||||
dynamodb_tables_pitr_enabled,
|
||||
)
|
||||
|
||||
check = dynamodb_tables_pitr_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_dynamodb
|
||||
def test_dynamodb_table_no_pitr(self):
|
||||
dynamodb_client = client("dynamodb", region_name=AWS_REGION)
|
||||
table = dynamodb_client.create_table(
|
||||
TableName="test1",
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "client", "AttributeType": "S"},
|
||||
{"AttributeName": "app", "AttributeType": "S"},
|
||||
],
|
||||
KeySchema=[
|
||||
{"AttributeName": "client", "KeyType": "HASH"},
|
||||
{"AttributeName": "app", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)["TableDescription"]
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DynamoDB
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.dynamodb.dynamodb_tables_pitr_enabled.dynamodb_tables_pitr_enabled.dynamodb_client",
|
||||
new=DynamoDB(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_tables_pitr_enabled.dynamodb_tables_pitr_enabled import (
|
||||
dynamodb_tables_pitr_enabled,
|
||||
)
|
||||
|
||||
check = dynamodb_tables_pitr_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"does not have point-in-time recovery enabled",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == table["TableName"]
|
||||
assert result[0].resource_arn == table["TableArn"]
|
||||
|
||||
@mock_dynamodb
|
||||
def test_dynamodb_table_with_pitr(self):
|
||||
dynamodb_client = client("dynamodb", region_name=AWS_REGION)
|
||||
table = dynamodb_client.create_table(
|
||||
TableName="test1",
|
||||
AttributeDefinitions=[
|
||||
{"AttributeName": "client", "AttributeType": "S"},
|
||||
{"AttributeName": "app", "AttributeType": "S"},
|
||||
],
|
||||
KeySchema=[
|
||||
{"AttributeName": "client", "KeyType": "HASH"},
|
||||
{"AttributeName": "app", "KeyType": "RANGE"},
|
||||
],
|
||||
BillingMode="PAY_PER_REQUEST",
|
||||
)["TableDescription"]
|
||||
dynamodb_client.update_continuous_backups(
|
||||
TableName="test1",
|
||||
PointInTimeRecoverySpecification={"PointInTimeRecoveryEnabled": True},
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_service import DynamoDB
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.dynamodb.dynamodb_tables_pitr_enabled.dynamodb_tables_pitr_enabled.dynamodb_client",
|
||||
new=DynamoDB(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.dynamodb.dynamodb_tables_pitr_enabled.dynamodb_tables_pitr_enabled import (
|
||||
dynamodb_tables_pitr_enabled,
|
||||
)
|
||||
|
||||
check = dynamodb_tables_pitr_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"has point-in-time recovery enabled", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == table["TableName"]
|
||||
assert result[0].resource_arn == table["TableArn"]
|
||||
@@ -0,0 +1,110 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client, resource
|
||||
from moto import mock_ec2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
EXAMPLE_AMI_ID = "ami-12c6146b"
|
||||
|
||||
|
||||
class Test_ec2_ami_public:
|
||||
@mock_ec2
|
||||
def test_no_amis(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ami_public.ec2_ami_public.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ami_public.ec2_ami_public import (
|
||||
ec2_ami_public,
|
||||
)
|
||||
|
||||
check = ec2_ami_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_ec2
|
||||
def test_one_private_ami(self):
|
||||
|
||||
ec2 = client("ec2", region_name="us-east-1")
|
||||
|
||||
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
|
||||
instance = reservation["Instances"][0]
|
||||
instance_id = instance["InstanceId"]
|
||||
|
||||
image_id = ec2.create_image(
|
||||
InstanceId=instance_id, Name="test-ami", Description="this is a test ami"
|
||||
)["ImageId"]
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ami_public.ec2_ami_public.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.ec2.ec2_ami_public.ec2_ami_public import (
|
||||
ec2_ami_public,
|
||||
)
|
||||
|
||||
check = ec2_ami_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == f"EC2 AMI {image_id} is not public."
|
||||
assert result[0].resource_id == image_id
|
||||
|
||||
@mock_ec2
|
||||
def test_one_public_ami(self):
|
||||
|
||||
ec2 = client("ec2", region_name="us-east-1")
|
||||
|
||||
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
|
||||
instance = reservation["Instances"][0]
|
||||
instance_id = instance["InstanceId"]
|
||||
|
||||
image_id = ec2.create_image(
|
||||
InstanceId=instance_id, Name="test-ami", Description="this is a test ami"
|
||||
)["ImageId"]
|
||||
|
||||
image = resource("ec2", region_name="us-east-1").Image(image_id)
|
||||
ADD_GROUP_ARGS = {
|
||||
"ImageId": image_id,
|
||||
"Attribute": "launchPermission",
|
||||
"OperationType": "add",
|
||||
"UserGroups": ["all"],
|
||||
}
|
||||
image.modify_attribute(**ADD_GROUP_ARGS)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ami_public.ec2_ami_public.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.ec2.ec2_ami_public.ec2_ami_public import (
|
||||
ec2_ami_public,
|
||||
)
|
||||
|
||||
check = ec2_ami_public()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended == f"EC2 AMI {image_id} is currently public."
|
||||
)
|
||||
assert result[0].resource_id == image_id
|
||||
@@ -0,0 +1,71 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_ec2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
EXAMPLE_AMI_ID = "ami-12c6146b"
|
||||
|
||||
|
||||
class Test_ec2_ebs_default_encryption:
|
||||
@mock_ec2
|
||||
def test_ec2_ebs_encryption_enabled(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||
ec2_client.enable_ebs_encryption_by_default()
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_default_encryption.ec2_ebs_default_encryption.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_default_encryption.ec2_ebs_default_encryption import (
|
||||
ec2_ebs_default_encryption,
|
||||
)
|
||||
|
||||
check = ec2_ebs_default_encryption()
|
||||
results = check.execute()
|
||||
|
||||
# One result per region
|
||||
assert len(results) == 25
|
||||
for result in results:
|
||||
if result.region == AWS_REGION:
|
||||
assert result.status == "PASS"
|
||||
assert search(
|
||||
"EBS Default Encryption is activated",
|
||||
result.status_extended,
|
||||
)
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_ebs_encryption_disabled(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_default_encryption.ec2_ebs_default_encryption.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_default_encryption.ec2_ebs_default_encryption import (
|
||||
ec2_ebs_default_encryption,
|
||||
)
|
||||
|
||||
check = ec2_ebs_default_encryption()
|
||||
result = check.execute()
|
||||
|
||||
# One result per region
|
||||
assert len(result) == 25
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"EBS Default Encryption is not activated",
|
||||
result[0].status_extended,
|
||||
)
|
||||
@@ -0,0 +1,108 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client, resource
|
||||
from moto import mock_ec2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_ec2_ebs_public_snapshot:
|
||||
@mock_ec2
|
||||
def test_ec2_default_snapshots(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot import (
|
||||
ec2_ebs_public_snapshot,
|
||||
)
|
||||
|
||||
check = ec2_ebs_public_snapshot()
|
||||
result = check.execute()
|
||||
|
||||
# Default snapshots
|
||||
assert len(result) == 1485
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_public_snapshot(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||
volume = ec2.create_volume(Size=80, AvailabilityZone=f"{AWS_REGION}a")
|
||||
snapshot = volume.create_snapshot(Description="testsnap")
|
||||
ec2_client.modify_snapshot_attribute(
|
||||
SnapshotId=snapshot.id,
|
||||
Attribute="createVolumePermission",
|
||||
OperationType="add",
|
||||
GroupNames=["all"],
|
||||
)
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot import (
|
||||
ec2_ebs_public_snapshot,
|
||||
)
|
||||
|
||||
check = ec2_ebs_public_snapshot()
|
||||
results = check.execute()
|
||||
|
||||
# Default snapshots + 1 created
|
||||
assert len(results) == 1486
|
||||
|
||||
for snap in results:
|
||||
if snap.resource_id == snapshot.id:
|
||||
assert snap.status == "FAIL"
|
||||
assert (
|
||||
snap.status_extended
|
||||
== f"EBS Snapshot {snapshot.id} is currently Public."
|
||||
)
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_private_snapshot(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
snapshot = volume = ec2.create_volume(
|
||||
Size=80, AvailabilityZone=f"{AWS_REGION}a", Encrypted=True
|
||||
)
|
||||
snapshot = volume.create_snapshot(Description="testsnap")
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_public_snapshot.ec2_ebs_public_snapshot import (
|
||||
ec2_ebs_public_snapshot,
|
||||
)
|
||||
|
||||
check = ec2_ebs_public_snapshot()
|
||||
results = check.execute()
|
||||
|
||||
# Default snapshots + 1 created
|
||||
assert len(results) == 1486
|
||||
|
||||
for snap in results:
|
||||
if snap.resource_id == snapshot.id:
|
||||
assert snap.status == "PASS"
|
||||
assert (
|
||||
snap.status_extended
|
||||
== f"EBS Snapshot {snapshot.id} is not Public."
|
||||
)
|
||||
@@ -0,0 +1,102 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import resource
|
||||
from moto import mock_ec2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_ec2_ebs_snapshots_encrypted:
|
||||
@mock_ec2
|
||||
def test_ec2_default_snapshots(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_snapshots_encrypted.ec2_ebs_snapshots_encrypted.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_snapshots_encrypted.ec2_ebs_snapshots_encrypted import (
|
||||
ec2_ebs_snapshots_encrypted,
|
||||
)
|
||||
|
||||
check = ec2_ebs_snapshots_encrypted()
|
||||
result = check.execute()
|
||||
|
||||
# Default snapshots
|
||||
assert len(result) == 1485
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_unencrypted_snapshot(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
volume = ec2.create_volume(Size=80, AvailabilityZone=f"{AWS_REGION}a")
|
||||
snapshot = volume.create_snapshot(Description="testsnap")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_snapshots_encrypted.ec2_ebs_snapshots_encrypted.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_snapshots_encrypted.ec2_ebs_snapshots_encrypted import (
|
||||
ec2_ebs_snapshots_encrypted,
|
||||
)
|
||||
|
||||
check = ec2_ebs_snapshots_encrypted()
|
||||
results = check.execute()
|
||||
|
||||
# Default snapshots + 1 created
|
||||
assert len(results) == 1486
|
||||
|
||||
for snap in results:
|
||||
if snap.resource_id == snapshot.id:
|
||||
assert snap.status == "FAIL"
|
||||
assert (
|
||||
snap.status_extended
|
||||
== f"EBS Snapshot {snapshot.id} is unencrypted."
|
||||
)
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_encrypted_snapshot(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
snapshot = volume = ec2.create_volume(
|
||||
Size=80, AvailabilityZone=f"{AWS_REGION}a", Encrypted=True
|
||||
)
|
||||
snapshot = volume.create_snapshot(Description="testsnap")
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_snapshots_encrypted.ec2_ebs_snapshots_encrypted.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_snapshots_encrypted.ec2_ebs_snapshots_encrypted import (
|
||||
ec2_ebs_snapshots_encrypted,
|
||||
)
|
||||
|
||||
check = ec2_ebs_snapshots_encrypted()
|
||||
results = check.execute()
|
||||
|
||||
# Default snapshots + 1 created
|
||||
assert len(results) == 1486
|
||||
|
||||
for snap in results:
|
||||
if snap.resource_id == snapshot.id:
|
||||
assert snap.status == "PASS"
|
||||
assert (
|
||||
snap.status_extended
|
||||
== f"EBS Snapshot {snapshot.id} is encrypted."
|
||||
)
|
||||
@@ -0,0 +1,92 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import resource
|
||||
from moto import mock_ec2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_ec2_ebs_volume_encryption:
|
||||
@mock_ec2
|
||||
def test_ec2_no_volumes(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption import (
|
||||
ec2_ebs_volume_encryption,
|
||||
)
|
||||
|
||||
check = ec2_ebs_volume_encryption()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_unencrypted_volume(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
volume = ec2.create_volume(Size=80, AvailabilityZone=f"{AWS_REGION}a")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption import (
|
||||
ec2_ebs_volume_encryption,
|
||||
)
|
||||
|
||||
check = ec2_ebs_volume_encryption()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended == f"EBS Snapshot {volume.id} is unencrypted."
|
||||
)
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_encrypted_volume(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
volume = ec2.create_volume(
|
||||
Size=80, AvailabilityZone=f"{AWS_REGION}a", Encrypted=True
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_ebs_volume_encryption.ec2_ebs_volume_encryption import (
|
||||
ec2_ebs_volume_encryption,
|
||||
)
|
||||
|
||||
check = ec2_ebs_volume_encryption()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended == f"EBS Snapshot {volume.id} is encrypted."
|
||||
)
|
||||
@@ -0,0 +1,104 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_ec2
|
||||
|
||||
from prowler.config.config import get_config_var
|
||||
|
||||
EXAMPLE_AMI_ID = "ami-12c6146b"
|
||||
shodan_api_key = get_config_var("shodan_api_key")
|
||||
|
||||
|
||||
class Test_ec2_elastic_ip_shodan:
|
||||
if shodan_api_key:
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_one_instances_no_public_ip(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2_client = client("ec2")
|
||||
# Create EC2 Instance
|
||||
ec2_client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import (
|
||||
current_audit_info,
|
||||
)
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_elastic_ip_shodan.ec2_elastic_ip_shodan.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_elastic_ip_shodan.ec2_elastic_ip_shodan import (
|
||||
ec2_elastic_ip_shodan,
|
||||
)
|
||||
|
||||
check = ec2_elastic_ip_shodan()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_one_unattached_eip(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2_client = client("ec2")
|
||||
# Create EC2 Instance
|
||||
ec2_client.allocate_address(Domain="vpc")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import (
|
||||
current_audit_info,
|
||||
)
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_elastic_ip_shodan.ec2_elastic_ip_shodan.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_elastic_ip_shodan.ec2_elastic_ip_shodan import (
|
||||
ec2_elastic_ip_shodan,
|
||||
)
|
||||
|
||||
check = ec2_elastic_ip_shodan()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_ec2
|
||||
def test_ec2_one_attached_eip(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2_client = client("ec2")
|
||||
# Create EC2 Instance
|
||||
instance = ec2_client.run_instances(
|
||||
ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1
|
||||
)
|
||||
allocation = ec2_client.allocate_address(Domain="vpc")
|
||||
ec2_client.associate_address(
|
||||
AllocationId=allocation["AllocationId"],
|
||||
InstanceId=instance["Instances"][0]["InstanceId"],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import (
|
||||
current_audit_info,
|
||||
)
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_elastic_ip_shodan.ec2_elastic_ip_shodan.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_elastic_ip_shodan.ec2_elastic_ip_shodan import (
|
||||
ec2_elastic_ip_shodan,
|
||||
)
|
||||
|
||||
check = ec2_elastic_ip_shodan()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
@@ -0,0 +1,105 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client, resource
|
||||
from moto import mock_ec2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
EXAMPLE_AMI_ID = "ami-12c6146b"
|
||||
|
||||
|
||||
class Test_ec2_elastic_ip_unassgined:
|
||||
@mock_ec2
|
||||
def test_no_eips(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_elastic_ip_unassgined.ec2_elastic_ip_unassgined.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_elastic_ip_unassgined.ec2_elastic_ip_unassgined import (
|
||||
ec2_elastic_ip_unassgined,
|
||||
)
|
||||
|
||||
check = ec2_elastic_ip_unassgined()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_ec2
|
||||
def test_eip_unassociated(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||
ec2_client.allocate_address(Domain="vpc", Address="127.38.43.222")
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_elastic_ip_unassgined.ec2_elastic_ip_unassgined.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_elastic_ip_unassgined.ec2_elastic_ip_unassgined import (
|
||||
ec2_elastic_ip_unassgined,
|
||||
)
|
||||
|
||||
check = ec2_elastic_ip_unassgined()
|
||||
results = check.execute()
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status == "FAIL"
|
||||
assert search(
|
||||
"is not associated",
|
||||
results[0].status_extended,
|
||||
)
|
||||
|
||||
@mock_ec2
|
||||
def test_eip_associated(self):
|
||||
# Create EC2 Mocked Resources
|
||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||
ec2_resource = resource("ec2", region_name=AWS_REGION)
|
||||
|
||||
reservation = ec2_client.run_instances(
|
||||
ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1
|
||||
)
|
||||
instance = ec2_resource.Instance(reservation["Instances"][0]["InstanceId"])
|
||||
|
||||
eip = ec2_client.allocate_address(Domain="vpc")
|
||||
|
||||
eip = ec2_resource.VpcAddress(eip["AllocationId"])
|
||||
|
||||
ec2_client.associate_address(
|
||||
InstanceId=instance.id, AllocationId=eip.allocation_id
|
||||
)
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_elastic_ip_unassgined.ec2_elastic_ip_unassgined.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_elastic_ip_unassgined.ec2_elastic_ip_unassgined import (
|
||||
ec2_elastic_ip_unassgined,
|
||||
)
|
||||
|
||||
check = ec2_elastic_ip_unassgined()
|
||||
results = check.execute()
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status == "PASS"
|
||||
assert search(
|
||||
"is associated",
|
||||
results[0].status_extended,
|
||||
)
|
||||
@@ -0,0 +1,114 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import resource
|
||||
from moto import mock_ec2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
EXAMPLE_AMI_ID = "ami-12c6146b"
|
||||
|
||||
|
||||
class Test_ec2_instance_imdsv2_enabled:
|
||||
@mock_ec2
|
||||
def test_ec2_no_instances(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_imdsv2_enabled.ec2_instance_imdsv2_enabled.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_imdsv2_enabled.ec2_instance_imdsv2_enabled import (
|
||||
ec2_instance_imdsv2_enabled,
|
||||
)
|
||||
|
||||
check = ec2_instance_imdsv2_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_ec2
|
||||
def test_one_compliant_ec2(self):
|
||||
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
instance = ec2.create_instances(
|
||||
ImageId=EXAMPLE_AMI_ID,
|
||||
MinCount=1,
|
||||
MaxCount=1,
|
||||
MetadataOptions={
|
||||
"HttpTokens": "required",
|
||||
"HttpEndpoint": "enabled",
|
||||
},
|
||||
)[0]
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_imdsv2_enabled.ec2_instance_imdsv2_enabled.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
) as service_client:
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_imdsv2_enabled.ec2_instance_imdsv2_enabled import (
|
||||
ec2_instance_imdsv2_enabled,
|
||||
)
|
||||
|
||||
service_client.instances[0].http_endpoint = "enabled"
|
||||
service_client.instances[0].http_tokens = "required"
|
||||
|
||||
check = ec2_instance_imdsv2_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
f"EC2 Instance {instance.id} has IMDSv2 enabled and required",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == instance.id
|
||||
|
||||
@mock_ec2
|
||||
def test_one_uncompliant_ec2(self):
|
||||
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
instance = ec2.create_instances(
|
||||
ImageId=EXAMPLE_AMI_ID,
|
||||
MinCount=1,
|
||||
MaxCount=1,
|
||||
MetadataOptions={
|
||||
"HttpTokens": "optional",
|
||||
"HttpEndpoint": "disabled",
|
||||
},
|
||||
)[0]
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_imdsv2_enabled.ec2_instance_imdsv2_enabled.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
) as service_client:
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_imdsv2_enabled.ec2_instance_imdsv2_enabled import (
|
||||
ec2_instance_imdsv2_enabled,
|
||||
)
|
||||
|
||||
service_client.instances[0].http_endpoint = "disabled"
|
||||
service_client.instances[0].http_tokens = "optional"
|
||||
|
||||
check = ec2_instance_imdsv2_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"EC2 Instance {instance.id} has IMDSv2 disabled or not required",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == instance.id
|
||||
@@ -0,0 +1,129 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client, resource
|
||||
from moto import mock_ec2, mock_iam
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
EXAMPLE_AMI_ID = "ami-12c6146b"
|
||||
|
||||
|
||||
class Test_ec2_instance_internet_facing_with_instance_profile:
|
||||
@mock_ec2
|
||||
def test_ec2_no_instances(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_internet_facing_with_instance_profile.ec2_instance_internet_facing_with_instance_profile.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_internet_facing_with_instance_profile.ec2_instance_internet_facing_with_instance_profile import (
|
||||
ec2_instance_internet_facing_with_instance_profile,
|
||||
)
|
||||
|
||||
check = ec2_instance_internet_facing_with_instance_profile()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_iam
|
||||
@mock_ec2
|
||||
def test_one_compliant_ec2(self):
|
||||
iam = client("iam", "us-west-1")
|
||||
profile_name = "fake_profile"
|
||||
_ = iam.create_instance_profile(
|
||||
InstanceProfileName=profile_name,
|
||||
)
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
|
||||
instance = ec2.create_instances(
|
||||
ImageId=EXAMPLE_AMI_ID,
|
||||
MinCount=1,
|
||||
MaxCount=1,
|
||||
IamInstanceProfile={"Name": profile_name},
|
||||
NetworkInterfaces=[
|
||||
{
|
||||
"DeviceIndex": 0,
|
||||
"SubnetId": subnet.id,
|
||||
"AssociatePublicIpAddress": False,
|
||||
}
|
||||
],
|
||||
)[0]
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_internet_facing_with_instance_profile.ec2_instance_internet_facing_with_instance_profile.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_internet_facing_with_instance_profile.ec2_instance_internet_facing_with_instance_profile import (
|
||||
ec2_instance_internet_facing_with_instance_profile,
|
||||
)
|
||||
|
||||
check = ec2_instance_internet_facing_with_instance_profile()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
f"EC2 Instance {instance.id} is not internet facing with an instance profile",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == instance.id
|
||||
|
||||
@mock_iam
|
||||
@mock_ec2
|
||||
def test_one_non_compliant_ec2(self):
|
||||
iam = client("iam", "us-west-1")
|
||||
profile_name = "fake_profile"
|
||||
_ = iam.create_instance_profile(
|
||||
InstanceProfileName=profile_name,
|
||||
)
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
|
||||
instance = ec2.create_instances(
|
||||
ImageId=EXAMPLE_AMI_ID,
|
||||
MinCount=1,
|
||||
MaxCount=1,
|
||||
IamInstanceProfile={"Name": profile_name},
|
||||
NetworkInterfaces=[
|
||||
{
|
||||
"DeviceIndex": 0,
|
||||
"SubnetId": subnet.id,
|
||||
"AssociatePublicIpAddress": True,
|
||||
}
|
||||
],
|
||||
)[0]
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_internet_facing_with_instance_profile.ec2_instance_internet_facing_with_instance_profile.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_internet_facing_with_instance_profile.ec2_instance_internet_facing_with_instance_profile import (
|
||||
ec2_instance_internet_facing_with_instance_profile,
|
||||
)
|
||||
|
||||
check = ec2_instance_internet_facing_with_instance_profile()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"is internet-facing with Instance Profile", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == instance.id
|
||||
@@ -0,0 +1,106 @@
|
||||
import datetime
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import resource
|
||||
from dateutil.tz import tzutc
|
||||
from moto import mock_ec2
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
EXAMPLE_AMI_ID = "ami-12c6146b"
|
||||
|
||||
|
||||
class Test_ec2_instance_older_than_specific_days:
|
||||
@mock_ec2
|
||||
def test_ec2_no_instances(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_older_than_specific_days.ec2_instance_older_than_specific_days.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_older_than_specific_days.ec2_instance_older_than_specific_days import (
|
||||
ec2_instance_older_than_specific_days,
|
||||
)
|
||||
|
||||
check = ec2_instance_older_than_specific_days()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_ec2
|
||||
def test_one_compliant_ec2(self):
|
||||
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
instance = ec2.create_instances(
|
||||
ImageId=EXAMPLE_AMI_ID,
|
||||
MinCount=1,
|
||||
MaxCount=1,
|
||||
UserData="This is some user_data",
|
||||
)[0]
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_older_than_specific_days.ec2_instance_older_than_specific_days.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_older_than_specific_days.ec2_instance_older_than_specific_days import (
|
||||
ec2_instance_older_than_specific_days,
|
||||
)
|
||||
|
||||
check = ec2_instance_older_than_specific_days()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
f"EC2 Instance {instance.id} is not older", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == instance.id
|
||||
|
||||
@mock_ec2
|
||||
def test_one_old_ec2(self):
|
||||
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
instance = ec2.create_instances(
|
||||
ImageId=EXAMPLE_AMI_ID,
|
||||
MinCount=1,
|
||||
MaxCount=1,
|
||||
UserData="This is some user_data",
|
||||
)[0]
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_older_than_specific_days.ec2_instance_older_than_specific_days.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
) as service_client:
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_older_than_specific_days.ec2_instance_older_than_specific_days import (
|
||||
ec2_instance_older_than_specific_days,
|
||||
)
|
||||
|
||||
service_client.instances[0].launch_time = datetime.datetime(
|
||||
2021, 11, 1, 17, 18, tzinfo=tzutc()
|
||||
)
|
||||
|
||||
check = ec2_instance_older_than_specific_days()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
f"EC2 Instance {instance.id} is older", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == instance.id
|
||||
@@ -0,0 +1,122 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client, resource
|
||||
from moto import mock_ec2, mock_iam
|
||||
|
||||
AWS_REGION = "us-east-1"
|
||||
EXAMPLE_AMI_ID = "ami-12c6146b"
|
||||
|
||||
|
||||
class Test_ec2_instance_profile_attached:
|
||||
@mock_ec2
|
||||
def test_ec2_no_instances(self):
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_profile_attached.ec2_instance_profile_attached.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_profile_attached.ec2_instance_profile_attached import (
|
||||
ec2_instance_profile_attached,
|
||||
)
|
||||
|
||||
check = ec2_instance_profile_attached()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_iam
|
||||
@mock_ec2
|
||||
def test_one_compliant_ec2(self):
|
||||
iam = client("iam", "us-west-1")
|
||||
profile_name = "fake_profile"
|
||||
_ = iam.create_instance_profile(
|
||||
InstanceProfileName=profile_name,
|
||||
)
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
|
||||
instance = ec2.create_instances(
|
||||
ImageId=EXAMPLE_AMI_ID,
|
||||
MinCount=1,
|
||||
MaxCount=1,
|
||||
IamInstanceProfile={"Name": profile_name},
|
||||
NetworkInterfaces=[
|
||||
{
|
||||
"DeviceIndex": 0,
|
||||
"SubnetId": subnet.id,
|
||||
"AssociatePublicIpAddress": False,
|
||||
}
|
||||
],
|
||||
)[0]
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_profile_attached.ec2_instance_profile_attached.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_profile_attached.ec2_instance_profile_attached import (
|
||||
ec2_instance_profile_attached,
|
||||
)
|
||||
|
||||
check = ec2_instance_profile_attached()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"associated with Instance Profile Role",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == instance.id
|
||||
|
||||
@mock_ec2
|
||||
def test_one_non_compliant_ec2(self):
|
||||
ec2 = resource("ec2", region_name=AWS_REGION)
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
|
||||
instance = ec2.create_instances(
|
||||
ImageId=EXAMPLE_AMI_ID,
|
||||
MinCount=1,
|
||||
MaxCount=1,
|
||||
NetworkInterfaces=[
|
||||
{
|
||||
"DeviceIndex": 0,
|
||||
"SubnetId": subnet.id,
|
||||
"AssociatePublicIpAddress": True,
|
||||
}
|
||||
],
|
||||
)[0]
|
||||
|
||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
current_audit_info.audited_partition = "aws"
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.ec2.ec2_instance_profile_attached.ec2_instance_profile_attached.ec2_client",
|
||||
new=EC2(current_audit_info),
|
||||
):
|
||||
from prowler.providers.aws.services.ec2.ec2_instance_profile_attached.ec2_instance_profile_attached import (
|
||||
ec2_instance_profile_attached,
|
||||
)
|
||||
|
||||
check = ec2_instance_profile_attached()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"not associated with an Instance Profile", result[0].status_extended
|
||||
)
|
||||
assert result[0].resource_id == instance.id
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user