def test_prep_for_audit(self): rpa = ResourcePolicyAuditor(accounts=["012345678910"]) rpa.prep_for_audit() self.assertEqual(rpa.OBJECT_STORE['s3']['my-test-s3-bucket'], set(['012345678910'])) self.assertEqual(rpa.OBJECT_STORE['ACCOUNTS']['FRIENDLY'], set(['012345678910', '222222222222'])) self.assertEqual(rpa.OBJECT_STORE['ACCOUNTS']['THIRDPARTY'], set(['333333333333'])) self.assertEqual( set(rpa.OBJECT_STORE['userid'].keys()), set([ 'AIDA11111111111111111', 'AISA11111111111111111', 'AIDA22222222222222222', 'AISA22222222222222222', 'AIDA33333333333333333', 'AISA33333333333333333' ])) from ipaddr import IPNetwork self.assertEqual( set(rpa.OBJECT_STORE['cidr'].keys()), set([ '10.1.1.1/18', '172.16.11.11/32', '54.11.11.11/32', '10.2.2.2/18', '172.16.22.22/32', '54.22.22.22/32', '10.3.3.3/18', '172.16.33.33/32', '54.33.33.33/32' ])) self.assertEqual(set(rpa.OBJECT_STORE['vpc'].keys()), set(['vpc-11111111', 'vpc-22222222', 'vpc-33333333'])) self.assertEqual( set(rpa.OBJECT_STORE['vpce'].keys()), set(['vpce-11111111', 'vpce-22222222', 'vpce-33333333']))
def test_check_internet_accessible(self): rpa = ResourcePolicyAuditor(accounts=["012345678910"]) rpa.prep_for_audit() policy01 = dict(Version='2010-08-14', Statement=[ dict(Effect='Allow', Principal='arn:aws:iam::*:root', Action=['ec2:*'], Resource='*') ]) test_item = Item(account='TEST_ACCOUNT', config=dict(Policy=policy01)) def mock_add_issue(score, issue, item, notes=None, action_instructions=None): self.assertEqual(10, score) self.assertEqual('Internet Accessible', issue) self.assertEqual('Entity: [principal:*] Actions: ["ec2:*"]', notes) rpa.add_issue = lambda *args, **kwargs: mock_add_issue(*args, **kwargs) rpa.check_internet_accessible(test_item) policy02 = dict(Version='2010-08-14', Statement=[ dict(Effect='Allow', Principal='arn:aws:iam::012345678910:root', Action=['ec2:*'], Resource='*') ]) test_item = Item(account='TEST_ACCOUNT', config=dict(Policy=policy02)) def mock_add_issue_two(score, issue, item, notes=None): # should not get here self.assertTrue(False) rpa.add_issue = lambda *args, **kwargs: mock_add_issue_two( *args, **kwargs) rpa.check_internet_accessible(test_item)
def test_load_policies(self): policy01 = dict(Version='2012-10-08', Statement=[]) test_item = Item(account=None, config=dict(Policy=policy01)) rpa = ResourcePolicyAuditor(accounts=["012345678910"]) # Policy class has no equivelance test at the moment. # Compare the underlying dicts instead policies = [ policy.policy for policy in rpa.load_resource_policies(test_item) ] self.assertEqual([policy01], policies) policy02 = dict( Version='2012-10-08', Statement=[dict(Effect='Allow', Action='*', Resource='*')]) policy03 = dict( Version='2012-10-08', Statement=[dict(Effect='Allow', Action='lambda:*', Resource='*')]) policy04 = dict( Version='2012-10-08', Statement=[dict(Effect='Allow', Action='ec2:*', Resource='*')]) # simulate a lambda function, which contains multiple policies test_item = Item( account=None, config=dict(Policies=dict(Aliases=dict(stable=policy01), DEFAULT=policy02, Versions={ "3": policy03, "4": policy04 }))) rpa.policy_keys = [ 'Policies$Aliases$*', 'Policies$DEFAULT', 'Policies$Versions$*' ] policies = [ policy.policy for policy in rpa.load_resource_policies(test_item) ] self.assertEqual([policy01, policy02, policy03, policy04], policies)
def test_check_root_cross_account(self): rpa = ResourcePolicyAuditor(accounts=['TEST_ACCOUNT']) rpa.prep_for_audit() key0_friendly_cross_account = deepcopy(key0) key0_friendly_cross_account['Policy'][0]['Statement'][0]['Principal']['AWS'] \ = 'arn:aws:iam::222222222222:root' item = ChangeItem(account='TEST_ACCOUNT', arn='arn:aws:kms:us-east-1:012345678910:key/key_id', new_config=key0_friendly_cross_account) rpa.check_root_cross_account(item) self.assertEqual(len(item.audit_issues), 1) self.assertEqual(item.audit_issues[0].score, 6)
def test_check_unknown_cross_account(self): rpa = ResourcePolicyAuditor(accounts=["012345678910"]) rpa.prep_for_audit() policy01 = dict(Version='2010-08-14', Statement=[ dict(Effect='Allow', Principal='arn:aws:iam::444444444444:root', Action=['ec2:*'], Resource='*') ]) test_item = Item(account='TEST_ACCOUNT', config=dict(Policy=policy01)) def mock_add_issue(score, issue, item, notes=None): self.assertEqual(10, score) self.assertEqual('Unknown Access', issue) self.assertEqual( 'Entity: [principal:arn:aws:iam::444444444444:root] Actions: ["ec2:*"]', notes) rpa.add_issue = lambda *args, **kwargs: mock_add_issue(*args, **kwargs) rpa.check_unknown_cross_account(test_item)
def pre_test_setup(self): ResourcePolicyAuditor(accounts=['TEST_ACCOUNT']).OBJECT_STORE.clear() account_type_result = AccountType(name='AWS') db.session.add(account_type_result) db.session.commit() # main account = Account(identifier="012345678910", name="TEST_ACCOUNT", account_type_id=account_type_result.id, notes="TEST_ACCOUNT", third_party=False, active=True) # friendly account2 = Account(identifier="222222222222", name="TEST_ACCOUNT_TWO", account_type_id=account_type_result.id, notes="TEST_ACCOUNT_TWO", third_party=False, active=True) # third party account3 = Account(identifier="333333333333", name="TEST_ACCOUNT_THREE", account_type_id=account_type_result.id, notes="TEST_ACCOUNT_THREE", third_party=True, active=True) db.session.add(account) db.session.add(account2) db.session.add(account3) db.session.commit() datastore = Datastore() # S3 datastore.store('s3', 'us-east-1', 'TEST_ACCOUNT', 'my-test-s3-bucket', True, dict(), arn='arn:aws:s3:::my-test-s3-bucket') datastore.store('s3', 'us-east-1', 'TEST_ACCOUNT_TWO', 'my-test-s3-bucket-two', True, dict(), arn='arn:aws:s3:::my-test-s3-bucket-two') datastore.store('s3', 'us-east-1', 'TEST_ACCOUNT_THREE', 'my-test-s3-bucket-three', True, dict(), arn='arn:aws:s3:::my-test-s3-bucket-three') # IAM User datastore.store('iamuser', 'us-east-1', 'TEST_ACCOUNT', 'my-test-iam-user', True, dict(UserId='AIDA11111111111111111', UserName='******'), arn='arn:aws:iam::012345678910:user/my-test-iam-user') datastore.store( 'iamuser', 'us-east-1', 'TEST_ACCOUNT_TWO', 'my-test-iam-user-two', True, dict(UserId='AIDA22222222222222222', UserName='******'), arn='arn:aws:iam::222222222222:user/my-test-iam-user-two') datastore.store( 'iamuser', 'us-east-1', 'TEST_ACCOUNT_THREE', 'my-test-iam-user-three', True, dict(UserId='AIDA33333333333333333', UserName='******'), arn='arn:aws:iam::333333333333:user/my-test-iam-user-three') # IAM Role datastore.store('iamrole', 'us-east-1', 'TEST_ACCOUNT', 'my-test-iam-role', True, dict(RoleId='AISA11111111111111111', RoleName='my-test-iam-role'), arn='arn:aws:iam::012345678910:role/my-test-iam-role') datastore.store( 'iamrole', 'us-east-1', 'TEST_ACCOUNT_TWO', 'my-test-iam-role-two', True, dict(RoleId='AISA22222222222222222', RoleName='my-test-iam-role-two'), arn='arn:aws:iam::222222222222:role/my-test-iam-role-two') datastore.store( 'iamrole', 'us-east-1', 'TEST_ACCOUNT_THREE', 'my-test-iam-role-three', True, dict(RoleId='AISA33333333333333333', RoleName='my-test-iam-role-three'), arn='arn:aws:iam::333333333333:role/my-test-iam-role-three') # NAT Gateway datastore.store( 'natgateway', 'us-east-1', 'TEST_ACCOUNT', 'my-test-natgateway', True, dict(nat_gateway_addresses=[ dict(public_ip='54.11.11.11', private_ip='172.16.11.11') ]), arn=None) # natgateway has no ARN :( datastore.store( 'natgateway', 'us-east-1', 'TEST_ACCOUNT_TWO', 'my-test-natgateway-two', True, dict(nat_gateway_addresses=[ dict(public_ip='54.22.22.22', private_ip='172.16.22.22') ]), arn=None) # natgateway has no ARN :( datastore.store( 'natgateway', 'us-east-1', 'TEST_ACCOUNT_THREE', 'my-test-natgateway-three', True, dict(nat_gateway_addresses=[ dict(public_ip='54.33.33.33', private_ip='172.16.33.33') ]), arn=None) # natgateway has no ARN :( # VPC datastore.store( 'vpc', 'us-east-1', 'TEST_ACCOUNT', 'my-test-vpc', True, dict(id='vpc-11111111', cidr_block='10.1.1.1/18'), arn='arn:aws:ec2:us-east-1:012345678910:vpc/vpc-11111111') datastore.store( 'vpc', 'us-east-1', 'TEST_ACCOUNT_TWO', 'my-test-vpc-two', True, dict(id='vpc-22222222', cidr_block='10.2.2.2/18'), arn='arn:aws:ec2:us-east-1:222222222222:vpc/vpc-22222222') datastore.store( 'vpc', 'us-east-1', 'TEST_ACCOUNT_THREE', 'my-test-vpc-three', True, dict(id='vpc-33333333', cidr_block='10.3.3.3/18'), arn='arn:aws:ec2:us-east-1:333333333333:vpc/vpc-33333333') # VPC Service Endpoint (For S3 and things) datastore.store('endpoint', 'us-east-1', 'TEST_ACCOUNT', 'my-test-vpce', True, dict(id='vpce-11111111'), arn=None) # vpce has no ARN :( datastore.store('endpoint', 'us-east-1', 'TEST_ACCOUNT_TWO', 'my-test-vpce-two', True, dict(id='vpce-22222222'), arn=None) # vpce has no ARN :( datastore.store('endpoint', 'us-east-1', 'TEST_ACCOUNT_THREE', 'my-test-vpce-three', True, dict(id='vpce-33333333'), arn=None) # vpce has no ARN :(
def test_inspect_entity(self): rpa = ResourcePolicyAuditor(accounts=["012345678910"]) rpa.prep_for_audit() # All conditions are SAME account. policy01 = dict( Version='2010-08-14', Statement=[ dict(Effect='Allow', Principal='arn:aws:iam::012345678910:root', Action=['ec2:*'], Resource='*', Condition={ 'StringEquals': { 'AWS:SourceOwner': '012345678910', 'AWS:SourceARN': 'arn:aws:iam::012345678910:root', 'AWS:SourceVPC': 'vpc-11111111', 'AWS:Sourcevpce': 'vpce-11111111', 'AWS:username': '******' }, 'StringLike': { 'AWS:userid': [ 'AIDA11111111111111111:*', 'AISA11111111111111111:*' ] }, 'IpAddress': { 'AWS:SourceIP': ['54.11.11.11', '10.1.1.1/18', '172.16.11.11'] } }) ]) test_item = Item(account='TEST_ACCOUNT', config=None) policy = Policy(policy01) for who in policy.whos_allowed(): entity = Entity.from_tuple(who) self.assertEqual(set(['SAME']), rpa.inspect_entity(entity, test_item)) # All conditions are FRIENDLY account. policy02 = dict( Version='2010-08-14', Statement=[ dict(Effect='Allow', Principal='arn:aws:iam::222222222222:root', Action=['ec2:*'], Resource='*', Condition={ 'StringEquals': { 'AWS:SourceOwner': '222222222222', 'AWS:SourceARN': 'arn:aws:s3:::my-test-s3-bucket-two', 'AWS:SourceVPC': 'vpc-22222222', 'AWS:Sourcevpce': 'vpce-22222222', 'AWS:username': '******' }, 'StringLike': { 'AWS:userid': [ 'AIDA22222222222222222:*', 'AISA22222222222222222:*' ] }, 'IpAddress': { 'AWS:SourceIP': ['54.22.22.22', '10.2.2.2/18', '172.16.22.22'] } }) ]) test_item = Item(account='TEST_ACCOUNT', config=None) policy = Policy(policy02) for who in policy.whos_allowed(): entity = Entity.from_tuple(who) self.assertEqual(set(['FRIENDLY']), rpa.inspect_entity(entity, test_item)) # All conditions are THIRDPARTY account. policy03 = dict( Version='2010-08-14', Statement=[ dict(Effect='Allow', Principal='arn:aws:iam::333333333333:root', Action=['ec2:*'], Resource='*', Condition={ 'StringEquals': { 'AWS:SourceOwner': '333333333333', 'AWS:SourceARN': 'arn:aws:iam::333333333333:root', 'AWS:SourceVPC': 'vpc-33333333', 'AWS:Sourcevpce': 'vpce-33333333', 'AWS:username': '******' }, 'StringLike': { 'AWS:userid': [ 'AIDA33333333333333333:*', 'AISA33333333333333333:*' ] }, 'IpAddress': { 'AWS:SourceIP': ['54.33.33.33', '10.3.3.3/18', '172.16.33.33'] } }) ]) test_item = Item(account='TEST_ACCOUNT', config=None) policy = Policy(policy03) for who in policy.whos_allowed(): entity = Entity.from_tuple(who) self.assertEqual(set(['THIRDPARTY']), rpa.inspect_entity(entity, test_item)) # All conditions are from an UNKNOWN account. policy04 = dict( Version='2010-08-14', Statement=[ dict(Effect='Allow', Principal='arn:aws:iam::444444444444:root', Action=['ec2:*'], Resource='*', Condition={ 'StringEquals': { 'AWS:SourceOwner': '444444444444', 'AWS:SourceARN': 'arn:aws:iam::444444444444:root', 'AWS:SourceVPC': 'vpc-44444444', 'AWS:Sourcevpce': 'vpce-44444444', 'AWS:username': '******' }, 'StringLike': { 'AWS:userid': [ 'AIDA44444444444444444:*', 'AISA44444444444444444:*' ] }, 'IpAddress': { 'AWS:SourceIP': ['54.44.44.44', '10.4.4.4/18', '172.16.44.44'] } }) ]) test_item = Item(account='TEST_ACCOUNT', config=None) policy = Policy(policy04) for who in policy.whos_allowed(): entity = Entity.from_tuple(who) self.assertEqual(set(['UNKNOWN']), rpa.inspect_entity(entity, test_item))