mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
feat(services_testing): Add tests for EC2, IAM and S3 services (#1352)
Co-authored-by: Pepe Fagoaga <pepe@verica.io> Co-authored-by: sergargar <sergio@verica.io>
This commit is contained in:
@@ -10,8 +10,8 @@ from config.config import aws_services_json_file
|
||||
from lib.logger import logger
|
||||
from lib.utils.utils import open_file, parse_json_file
|
||||
from providers.aws.lib.arn.arn import arn_parsing
|
||||
from providers.aws.models import (
|
||||
AWS_Assume_Role,
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.lib.audit_info.models import (
|
||||
AWS_Audit_Info,
|
||||
AWS_Credentials,
|
||||
AWS_Organizations_Info,
|
||||
@@ -91,31 +91,12 @@ def provider_set_session(
|
||||
input_regions,
|
||||
organizations_role_arn,
|
||||
):
|
||||
|
||||
# Mark variable that stores all the info about the audit as global
|
||||
global current_audit_info
|
||||
|
||||
# Assumed AWS session
|
||||
assumed_session = None
|
||||
|
||||
# Setting session
|
||||
current_audit_info = AWS_Audit_Info(
|
||||
original_session=None,
|
||||
audit_session=None,
|
||||
audited_account=None,
|
||||
audited_user_id=None,
|
||||
audited_partition=None,
|
||||
audited_identity_arn=None,
|
||||
profile=input_profile,
|
||||
profile_region=None,
|
||||
credentials=None,
|
||||
assumed_role_info=AWS_Assume_Role(
|
||||
role_arn=None,
|
||||
session_duration=None,
|
||||
external_id=None,
|
||||
),
|
||||
audited_regions=input_regions,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
current_audit_info.profile = input_profile
|
||||
current_audit_info.audited_regions = input_regions
|
||||
|
||||
logger.info("Generating original session ...")
|
||||
# Create an global original session using only profile/basic credentials info
|
||||
|
||||
@@ -10,7 +10,7 @@ from providers.aws.aws_provider import (
|
||||
get_region_global_service,
|
||||
validate_credentials,
|
||||
)
|
||||
from providers.aws.models import AWS_Assume_Role, AWS_Audit_Info
|
||||
from providers.aws.lib.audit_info.models import AWS_Assume_Role, AWS_Audit_Info
|
||||
|
||||
ACCOUNT_ID = 123456789012
|
||||
|
||||
|
||||
26
providers/aws/lib/audit_info/audit_info.py
Normal file
26
providers/aws/lib/audit_info/audit_info.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from boto3 import session
|
||||
|
||||
from providers.aws.lib.audit_info.models import AWS_Assume_Role, AWS_Audit_Info
|
||||
|
||||
# Default Current Audit Info
|
||||
current_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=AWS_Assume_Role(
|
||||
role_arn=None,
|
||||
session_duration=None,
|
||||
external_id=None,
|
||||
),
|
||||
audited_regions=None,
|
||||
organizations_metadata=None,
|
||||
)
|
||||
0
providers/aws/lib/security_hub/__init__.py
Normal file
0
providers/aws/lib/security_hub/__init__.py
Normal file
@@ -7,7 +7,7 @@ from boto3 import session
|
||||
from config.config import json_asff_file_suffix, timestamp_utc
|
||||
from lib.logger import logger
|
||||
from lib.outputs.models import Check_Output_JSON_ASFF
|
||||
from providers.aws.models import AWS_Audit_Info
|
||||
from providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
|
||||
|
||||
def send_to_security_hub(
|
||||
4
providers/aws/services/ec2/ec2_client.py
Normal file
4
providers/aws/services/ec2/ec2_client.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
ec2_client = EC2(current_audit_info)
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
|
||||
|
||||
class ec2_ebs_public_snapshot(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
|
||||
|
||||
class ec2_ebs_snapshots_encrypted(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
|
||||
|
||||
class ec2_instance_public_ip(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
from providers.aws.services.ec2.lib.network_acls import check_network_acl
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
from providers.aws.services.ec2.lib.network_acls import check_network_acl
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
from providers.aws.services.ec2.lib.security_groups import check_security_group
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
from providers.aws.services.ec2.lib.security_groups import check_security_group
|
||||
|
||||
|
||||
class ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21(Check):
|
||||
def execute(self):
|
||||
findings = []
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
from providers.aws.services.ec2.lib.security_groups import check_security_group
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
from providers.aws.services.ec2.lib.security_groups import check_security_group
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
from providers.aws.services.ec2.lib.security_groups import check_security_group
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.ec2.ec2_service import ec2_client
|
||||
from providers.aws.services.ec2.ec2_client import ec2_client
|
||||
from providers.aws.services.ec2.lib.security_groups import check_security_group
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import threading
|
||||
from dataclasses import dataclass
|
||||
|
||||
from lib.logger import logger
|
||||
from providers.aws.aws_provider import current_audit_info, generate_regional_clients
|
||||
from providers.aws.aws_provider import generate_regional_clients
|
||||
|
||||
|
||||
################## EC2
|
||||
@@ -129,7 +129,7 @@ class EC2:
|
||||
)
|
||||
encrypted = False
|
||||
for page in describe_snapshots_paginator.paginate(
|
||||
OwnerIds=[self.audited_account]
|
||||
OwnerIds=[str(self.audited_account)]
|
||||
):
|
||||
for snapshot in page["Snapshots"]:
|
||||
if snapshot["Encrypted"]:
|
||||
@@ -234,6 +234,3 @@ class NetworkACL:
|
||||
self.id = id
|
||||
self.region = region
|
||||
self.entries = entries
|
||||
|
||||
|
||||
ec2_client = EC2(current_audit_info)
|
||||
|
||||
167
providers/aws/services/ec2/ec2_service_test.py
Normal file
167
providers/aws/services/ec2/ec2_service_test.py
Normal file
@@ -0,0 +1,167 @@
|
||||
from boto3 import client, resource, session
|
||||
from moto import mock_ec2
|
||||
|
||||
from providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from providers.aws.services.ec2.ec2_service import EC2
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
AWS_REGION = "us-east-1"
|
||||
|
||||
|
||||
class Test_EC2_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 EC2 Service
|
||||
@mock_ec2
|
||||
def test_service(self):
|
||||
# EC2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
ec2 = EC2(audit_info)
|
||||
assert ec2.service == "ec2"
|
||||
|
||||
# Test EC2 Client
|
||||
@mock_ec2
|
||||
def test_client(self):
|
||||
# EC2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
ec2 = EC2(audit_info)
|
||||
for client in ec2.regional_clients.values():
|
||||
assert client.__class__.__name__ == "EC2"
|
||||
|
||||
# Test EC2 Session
|
||||
@mock_ec2
|
||||
def test__get_session__(self):
|
||||
# EC2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
ec2 = EC2(audit_info)
|
||||
assert ec2.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test EC2 Session
|
||||
@mock_ec2
|
||||
def test_audited_account(self):
|
||||
# EC2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
ec2 = EC2(audit_info)
|
||||
assert ec2.audited_account == AWS_ACCOUNT_NUMBER
|
||||
|
||||
# Test EC2 Describe Instances
|
||||
@mock_ec2
|
||||
def test__describe_instances__(self):
|
||||
# Generate EC2 Client
|
||||
ec2_resource = resource("ec2", region_name=AWS_REGION)
|
||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||
# Get AMI image
|
||||
image_response = ec2_client.describe_images()
|
||||
image_id = image_response["Images"][0]["ImageId"]
|
||||
# Create EC2 Instances
|
||||
ec2_resource.create_instances(
|
||||
MinCount=2,
|
||||
MaxCount=2,
|
||||
ImageId=image_id,
|
||||
)
|
||||
# EC2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
ec2 = EC2(audit_info)
|
||||
assert len(ec2.instances) == len(
|
||||
ec2_client.describe_instances()["Reservations"][0]["Instances"]
|
||||
)
|
||||
|
||||
# Test EC2 Describe Security Groups
|
||||
@mock_ec2
|
||||
def test__describe_security_groups__(self):
|
||||
# Generate EC2 Client
|
||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||
# Create EC2 Security Group
|
||||
sg_id = ec2_client.create_security_group(
|
||||
Description="test-description",
|
||||
GroupName="test-security-group",
|
||||
)["GroupId"]
|
||||
# EC2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
ec2 = EC2(audit_info)
|
||||
assert sg_id in str(ec2.security_groups)
|
||||
|
||||
# Test EC2 Describe Nacls
|
||||
@mock_ec2
|
||||
def test__describe_network_acls__(self):
|
||||
# Generate EC2 Client
|
||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||
ec2_resource = resource("ec2", region_name=AWS_REGION)
|
||||
# Create EC2 VPC and SG
|
||||
vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"]
|
||||
nacl_id = ec2_resource.create_network_acl(
|
||||
VpcId=vpc_id,
|
||||
).id
|
||||
# EC2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
ec2 = EC2(audit_info)
|
||||
assert nacl_id in str(ec2.network_acls)
|
||||
|
||||
# Test EC2 Describe Snapshots
|
||||
@mock_ec2
|
||||
def test__describe_snapshots__(self):
|
||||
# Generate EC2 Client
|
||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||
ec2_resource = resource("ec2", region_name=AWS_REGION)
|
||||
# Create EC2 Volume and Snapshot
|
||||
volume_id = ec2_resource.create_volume(
|
||||
AvailabilityZone="us-east-1a",
|
||||
Size=80,
|
||||
VolumeType="gp2",
|
||||
).id
|
||||
snapshot_id = ec2_client.create_snapshot(
|
||||
VolumeId=volume_id,
|
||||
)["SnapshotId"]
|
||||
# EC2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
ec2 = EC2(audit_info)
|
||||
assert snapshot_id in str(ec2.snapshots)
|
||||
|
||||
# Test EC2 Describe Snapshots
|
||||
@mock_ec2
|
||||
def test__get_snapshot_public__(self):
|
||||
# Generate EC2 Client
|
||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||
ec2_resource = resource("ec2", region_name=AWS_REGION)
|
||||
# Create EC2 Volume and Snapshot
|
||||
volume_id = ec2_resource.create_volume(
|
||||
AvailabilityZone="us-east-1a",
|
||||
Size=80,
|
||||
VolumeType="gp2",
|
||||
).id
|
||||
snapshot_id = ec2_client.create_snapshot(
|
||||
VolumeId=volume_id,
|
||||
)["SnapshotId"]
|
||||
ec2_client.modify_snapshot_attribute(
|
||||
Attribute="createVolumePermission",
|
||||
GroupNames=[
|
||||
"all",
|
||||
],
|
||||
OperationType="add",
|
||||
SnapshotId=snapshot_id,
|
||||
)
|
||||
# EC2 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
ec2 = EC2(audit_info)
|
||||
for snapshot in ec2.snapshots:
|
||||
if snapshot.id == snapshot_id:
|
||||
assert snapshot.public == True
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_administrator_access_with_mfa(Check):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import datetime
|
||||
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
maximum_access_days = 1
|
||||
|
||||
|
||||
4
providers/aws/services/iam/iam_client.py
Normal file
4
providers/aws/services/iam/iam_client.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
iam_client = IAM(current_audit_info)
|
||||
@@ -1,7 +1,7 @@
|
||||
import datetime
|
||||
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
maximum_expiration_days = 30
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import datetime
|
||||
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
maximum_expiration_days = 90
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_no_root_access_key(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_password_policy_expires_passwords_within_90_days_or_less(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
# Does the tool analyze both users and roles, or just one or the other? --> Everything using AttachementCount.
|
||||
# Does the tool take a principal-centric or policy-centric approach? --> Policy-centric approach.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_root_hardware_mfa_enabled(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_root_mfa_enabled(Check):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import datetime
|
||||
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
maximum_expiration_days = 90
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import csv
|
||||
from dataclasses import dataclass
|
||||
|
||||
from lib.logger import logger
|
||||
from providers.aws.aws_provider import current_audit_info, get_region_global_service
|
||||
from providers.aws.aws_provider import get_region_global_service
|
||||
|
||||
|
||||
################## IAM
|
||||
@@ -312,6 +312,3 @@ class PasswordPolicy:
|
||||
self.max_age = max_age
|
||||
self.reuse_prevention = reuse_prevention
|
||||
self.hard_expiry = hard_expiry
|
||||
|
||||
|
||||
iam_client = IAM(current_audit_info)
|
||||
|
||||
376
providers/aws/services/iam/iam_service_test.py
Normal file
376
providers/aws/services/iam/iam_service_test.py
Normal file
@@ -0,0 +1,376 @@
|
||||
import json
|
||||
|
||||
from boto3 import client, session
|
||||
from moto import mock_iam
|
||||
|
||||
from providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
|
||||
|
||||
class Test_IAM_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 IAM Client
|
||||
@mock_iam
|
||||
def test__get_client__(self):
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
assert iam.client.__class__.__name__ == "IAM"
|
||||
|
||||
# Test IAM Session
|
||||
@mock_iam
|
||||
def test__get_session__(self):
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
assert iam.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test IAM Get Credential Report
|
||||
@mock_iam
|
||||
def test__get_credential_report__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create an IAM Users
|
||||
iam_client.create_user(
|
||||
UserName="user1",
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
assert len(iam.credential_report) == len(iam_client.list_users()["Users"])
|
||||
|
||||
# Test IAM Get Roles
|
||||
@mock_iam
|
||||
def test__get_roles__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create 2 IAM Roles
|
||||
iam_client.create_role(
|
||||
RoleName="role1",
|
||||
AssumeRolePolicyDocument="string",
|
||||
)
|
||||
iam_client.create_role(
|
||||
RoleName="role2",
|
||||
AssumeRolePolicyDocument="string",
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.roles) == len(iam_client.list_roles()["Roles"])
|
||||
|
||||
# Test IAM Get Groups
|
||||
@mock_iam
|
||||
def test__get_groups__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create 2 IAM Groups
|
||||
iam_client.create_group(
|
||||
GroupName="group1",
|
||||
)
|
||||
iam_client.create_group(
|
||||
GroupName="group2",
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
assert len(iam.groups) == len(iam_client.list_groups()["Groups"])
|
||||
|
||||
# Test IAM Get Users
|
||||
@mock_iam
|
||||
def test__get_users__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create 2 IAM Users
|
||||
iam_client.create_user(
|
||||
UserName="user1",
|
||||
)
|
||||
iam_client.create_user(
|
||||
UserName="user2",
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
assert len(iam.users) == len(iam_client.list_users()["Users"])
|
||||
|
||||
# Test IAM Get Customer Managed Policies
|
||||
@mock_iam
|
||||
def test__get_customer_managed_policies__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create a new IAM Policy
|
||||
policy_document = """
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement":
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:ListBucket",
|
||||
"Resource": "arn:aws:s3:::example_bucket"
|
||||
}
|
||||
}
|
||||
"""
|
||||
iam_client.create_policy(
|
||||
PolicyName="policy1",
|
||||
PolicyDocument=policy_document,
|
||||
)
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
assert len(iam.customer_managed_policies) == len(
|
||||
iam_client.list_policies(Scope="Local")["Policies"]
|
||||
)
|
||||
|
||||
# Test IAM Get Customer Managed Policies Version
|
||||
@mock_iam
|
||||
def test__get_customer_managed_policies_version__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Create a new IAM Policy
|
||||
policy_document = """
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement":
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:ListBucket",
|
||||
"Resource": "arn:aws:s3:::example_bucket"
|
||||
}
|
||||
}
|
||||
"""
|
||||
iam_client.create_policy(
|
||||
PolicyName="policy1",
|
||||
PolicyDocument=policy_document,
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.customer_managed_policies) == 1
|
||||
assert iam.customer_managed_policies[0]["PolicyDocument"] == json.loads(
|
||||
policy_document
|
||||
)
|
||||
|
||||
# Test IAM Get Account Summary
|
||||
@mock_iam
|
||||
def test__get_account_summary__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
account_summary = iam_client.get_account_summary()
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert iam.account_summary == account_summary
|
||||
|
||||
# Test IAM Get Password Policy
|
||||
@mock_iam
|
||||
def test__get_password_policy__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Update Password Policy
|
||||
min_password_length = 123
|
||||
require_symbols = False
|
||||
require_numbers = True
|
||||
require_upper = True
|
||||
require_lower = False
|
||||
allow_users_to_change = True
|
||||
max_password_age = 123
|
||||
password_reuse_prevention = 24
|
||||
hard_expiry = True
|
||||
|
||||
iam_client.update_account_password_policy(
|
||||
MinimumPasswordLength=min_password_length,
|
||||
RequireSymbols=require_symbols,
|
||||
RequireNumbers=require_numbers,
|
||||
RequireUppercaseCharacters=require_upper,
|
||||
RequireLowercaseCharacters=require_lower,
|
||||
AllowUsersToChangePassword=allow_users_to_change,
|
||||
MaxPasswordAge=max_password_age,
|
||||
PasswordReusePrevention=password_reuse_prevention,
|
||||
HardExpiry=hard_expiry,
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert iam.password_policy.length == min_password_length
|
||||
assert iam.password_policy.symbols == require_symbols
|
||||
assert iam.password_policy.numbers == require_numbers
|
||||
assert iam.password_policy.uppercase == require_upper
|
||||
assert iam.password_policy.lowercase == require_lower
|
||||
assert iam.password_policy.allow_change == allow_users_to_change
|
||||
assert iam.password_policy.expiration == True
|
||||
assert iam.password_policy.max_age == max_password_age
|
||||
assert iam.password_policy.reuse_prevention == password_reuse_prevention
|
||||
assert iam.password_policy.hard_expiry == hard_expiry
|
||||
|
||||
# Test IAM List MFA Device
|
||||
@mock_iam
|
||||
def test__list_mfa_devices__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Generate IAM user
|
||||
iam_client.create_user(
|
||||
UserName="user1",
|
||||
)
|
||||
# Create virtual MFA device
|
||||
mfa_device_name = "test-mfa-device"
|
||||
virtual_mfa_device = iam_client.create_virtual_mfa_device(
|
||||
VirtualMFADeviceName=mfa_device_name,
|
||||
)
|
||||
iam_client.enable_mfa_device(
|
||||
UserName="user1",
|
||||
SerialNumber=virtual_mfa_device["VirtualMFADevice"]["SerialNumber"],
|
||||
AuthenticationCode1="123456",
|
||||
AuthenticationCode2="123456",
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.users) == 1
|
||||
assert len(iam.users[0].mfa_devices) == 1
|
||||
assert (
|
||||
iam.users[0].mfa_devices[0].serial_number
|
||||
== f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa/{mfa_device_name}"
|
||||
)
|
||||
assert iam.users[0].mfa_devices[0].type == "mfa"
|
||||
|
||||
# Test IAM List Virtual MFA Device
|
||||
@mock_iam
|
||||
def test__list_virtual_mfa_devices__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Generate IAM user
|
||||
username = "user1"
|
||||
iam_client.create_user(
|
||||
UserName=username,
|
||||
)
|
||||
# Create virtual MFA device
|
||||
mfa_device_name = "test-mfa-device"
|
||||
virtual_mfa_device = iam_client.create_virtual_mfa_device(
|
||||
VirtualMFADeviceName=mfa_device_name,
|
||||
)
|
||||
iam_client.enable_mfa_device(
|
||||
UserName=username,
|
||||
SerialNumber=virtual_mfa_device["VirtualMFADevice"]["SerialNumber"],
|
||||
AuthenticationCode1="123456",
|
||||
AuthenticationCode2="123456",
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.virtual_mfa_devices) == 1
|
||||
assert (
|
||||
iam.virtual_mfa_devices[0]["SerialNumber"]
|
||||
== f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa/{mfa_device_name}"
|
||||
)
|
||||
assert iam.virtual_mfa_devices[0]["User"]["UserName"] == username
|
||||
|
||||
# Test IAM Get Group Users
|
||||
@mock_iam
|
||||
def test__get_group_users__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Generate IAM user
|
||||
username = "user1"
|
||||
iam_client.create_user(
|
||||
UserName=username,
|
||||
)
|
||||
# Generate IAM group
|
||||
group = "test-group"
|
||||
iam_client.create_group(GroupName=group)
|
||||
# Add user to group
|
||||
iam_client.add_user_to_group(GroupName=group, UserName=username)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.groups) == 1
|
||||
assert iam.groups[0].name == group
|
||||
assert iam.groups[0].arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:group/{group}"
|
||||
assert len(iam.groups[0].users) == 1
|
||||
assert iam.groups[0].users[0].name == username
|
||||
|
||||
# Test IAM List Attached Group Policies
|
||||
@mock_iam
|
||||
def test__list_attached_group_policies__(self):
|
||||
# Generate IAM Client
|
||||
iam_client = client("iam")
|
||||
# Generate IAM user
|
||||
username = "user1"
|
||||
iam_client.create_user(
|
||||
UserName=username,
|
||||
)
|
||||
# Generate IAM group
|
||||
group = "test-group"
|
||||
iam_client.create_group(GroupName=group)
|
||||
|
||||
# Create a new IAM Policy
|
||||
policy_document = """
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement":
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:ListBucket",
|
||||
"Resource": "arn:aws:s3:::example_bucket"
|
||||
}
|
||||
}
|
||||
"""
|
||||
policy_name = "policy1"
|
||||
policy = iam_client.create_policy(
|
||||
PolicyName=policy_name,
|
||||
PolicyDocument=policy_document,
|
||||
)
|
||||
|
||||
# Attach group policy
|
||||
iam_client.attach_group_policy(
|
||||
GroupName=group, PolicyArn=policy["Policy"]["Arn"]
|
||||
)
|
||||
|
||||
# IAM client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
iam = IAM(audit_info)
|
||||
|
||||
assert len(iam.groups) == 1
|
||||
assert iam.groups[0].name == group
|
||||
assert len(iam.groups[0].attached_policies) == 1
|
||||
assert iam.groups[0].attached_policies[0]["PolicyName"] == policy_name
|
||||
assert (
|
||||
iam.groups[0].attached_policies[0]["PolicyArn"] == policy["Policy"]["Arn"]
|
||||
)
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_user_hardware_mfa_enabled(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_user_mfa_enabled_console_access(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.iam.iam_service import iam_client
|
||||
from providers.aws.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_user_two_active_access_key(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.s3.s3_service import s3_client
|
||||
from providers.aws.services.s3.s3_client import s3_client
|
||||
|
||||
|
||||
class s3_bucket_object_versioning(Check):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from lib.check.models import Check, Check_Report
|
||||
from providers.aws.services.s3.s3_service import s3_client
|
||||
from providers.aws.services.s3.s3_client import s3_client
|
||||
|
||||
|
||||
class s3_bucket_server_access_logging_enabled(Check):
|
||||
|
||||
4
providers/aws/services/s3/s3_client.py
Normal file
4
providers/aws/services/s3/s3_client.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||
from providers.aws.services.s3.s3_service import S3
|
||||
|
||||
s3_client = S3(current_audit_info)
|
||||
@@ -88,6 +88,3 @@ class Bucket:
|
||||
self.versioning = False
|
||||
self.logging = False
|
||||
self.region = region
|
||||
|
||||
|
||||
s3_client = S3(current_audit_info)
|
||||
|
||||
151
providers/aws/services/s3/s3_service_test.py
Normal file
151
providers/aws/services/s3/s3_service_test.py
Normal file
@@ -0,0 +1,151 @@
|
||||
from boto3 import client, session
|
||||
from moto import mock_s3
|
||||
|
||||
from providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||
from providers.aws.services.s3.s3_service import S3
|
||||
|
||||
AWS_ACCOUNT_NUMBER = 123456789012
|
||||
|
||||
|
||||
class Test_S3_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 S3 Service
|
||||
@mock_s3
|
||||
def test_service(self):
|
||||
# S3 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
s3 = S3(audit_info)
|
||||
assert s3.service == "s3"
|
||||
|
||||
# Test S3 Client
|
||||
@mock_s3
|
||||
def test_client(self):
|
||||
# S3 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
s3 = S3(audit_info)
|
||||
assert s3.client.__class__.__name__ == "S3"
|
||||
|
||||
# Test S3 Session
|
||||
@mock_s3
|
||||
def test__get_session__(self):
|
||||
# S3 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
s3 = S3(audit_info)
|
||||
assert s3.session.__class__.__name__ == "Session"
|
||||
|
||||
# Test S3 Regional Clients
|
||||
# @mock_s3
|
||||
# def test_regional_clients(self):
|
||||
# # S3 client for this test class
|
||||
# audit_info = self.set_mocked_audit_info()
|
||||
# s3 = S3(audit_info)
|
||||
# print(s3.regional_clients.keys())
|
||||
|
||||
# Test S3 Session
|
||||
@mock_s3
|
||||
def test_audited_account(self):
|
||||
# S3 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
s3 = S3(audit_info)
|
||||
assert s3.audited_account == AWS_ACCOUNT_NUMBER
|
||||
|
||||
# Test S3 List Buckets
|
||||
@mock_s3
|
||||
def test__list_buckets__(self):
|
||||
# Generate S3 Client
|
||||
s3_client = client("s3")
|
||||
# Create S3 Bucket
|
||||
bucket_name = "test-bucket"
|
||||
s3_client.create_bucket(Bucket=bucket_name)
|
||||
|
||||
# S3 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
s3 = S3(audit_info)
|
||||
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
|
||||
# Test S3 Get Bucket Versioning
|
||||
@mock_s3
|
||||
def test__get_bucket_versioning__(self):
|
||||
# Generate S3 Client
|
||||
s3_client = client("s3")
|
||||
# Create S3 Bucket
|
||||
bucket_name = "test-bucket"
|
||||
s3_client.create_bucket(Bucket=bucket_name)
|
||||
# Set Bucket Versioning
|
||||
s3_client.put_bucket_versioning(
|
||||
Bucket=bucket_name,
|
||||
VersioningConfiguration={"MFADelete": "Disabled", "Status": "Enabled"},
|
||||
)
|
||||
# S3 client for this test class
|
||||
audit_info = self.set_mocked_audit_info()
|
||||
s3 = S3(audit_info)
|
||||
assert len(s3.buckets) == 1
|
||||
assert s3.buckets[0].name == bucket_name
|
||||
assert s3.buckets[0].versioning == True
|
||||
|
||||
# Test S3 Get Bucket Versioning
|
||||
# @mock_s3
|
||||
# def test__get_bucket_logging__(self):
|
||||
# # Generate S3 Client
|
||||
# s3_client = client("s3")
|
||||
# # Create S3 Bucket
|
||||
# bucket_name = "test-bucket"
|
||||
# s3_client.create_bucket(
|
||||
# Bucket=bucket_name,
|
||||
# ACL='private'
|
||||
# )
|
||||
# # Set Bucket Logging
|
||||
# s3_client.put_bucket_logging(
|
||||
# Bucket=bucket_name,
|
||||
# BucketLoggingStatus={
|
||||
# 'LoggingEnabled': {
|
||||
# 'TargetBucket': bucket_name,
|
||||
# 'TargetGrants': [
|
||||
# {
|
||||
# 'Grantee': {
|
||||
# 'Type': 'Group',
|
||||
# 'URI': 'http://acs.amazonaws.com/groups/s3/LogDelivery'
|
||||
# },
|
||||
# 'Permission': 'READ_ACP'
|
||||
# },
|
||||
# {
|
||||
# 'Grantee': {
|
||||
# 'Type': 'Group',
|
||||
# 'URI': 'http://acs.amazonaws.com/groups/s3/LogDelivery'
|
||||
# },
|
||||
# 'Permission': 'WRITE'
|
||||
# }
|
||||
# ],
|
||||
# 'TargetPrefix': 'test-prefix'
|
||||
# }
|
||||
# }
|
||||
# )
|
||||
# # S3 client for this test class
|
||||
# audit_info = self.set_mocked_audit_info()
|
||||
# s3 = S3(audit_info)
|
||||
# print(s3.buckets)
|
||||
# assert len(s3.buckets) == 1
|
||||
# assert s3.buckets[0].name == bucket_name
|
||||
# assert s3.buckets[0].versioning == True
|
||||
Reference in New Issue
Block a user