def test_from_account_number(self): proper_account_numbers = [ "012345678912", "123456789101", "123456789101" ] improper_account_numbers = [ "*", "O12345678912", # 'O' instead of '0' "asdfqwer", "123456", "89789456314356132168978945", "568947897*", ] # Proper account number tests: for accnt in proper_account_numbers: logger.info("Testing Proper Account Number: {}".format(accnt)) arn_obj = ARN(accnt) self.assertFalse(arn_obj.error) # Improper account number tests: for accnt in improper_account_numbers: logger.info("Testing IMPROPER Account Number: {}".format(accnt)) arn_obj = ARN(accnt) self.assertTrue(arn_obj.error)
def get_trusted_principal_arns(self, resource_type): principals = list( filter(lambda x: ARN(x).name, self._get_trusted_principals('AWS'))) return [ ARN(principal) for principal in principals if ARN(principal).name.split('/')[0] == resource_type ]
def test_from_account_number(self): proper_account_numbers = [ '012345678912', '123456789101', '123456789101' ] improper_account_numbers = [ '*', 'O12345678912', # 'O' instead of '0' 'asdfqwer', '123456', '89789456314356132168978945', '568947897*' ] # Proper account number tests: for accnt in proper_account_numbers: logger.info('Testing Proper Account Number: {}'.format(accnt)) arn_obj = ARN(accnt) self.assertFalse(arn_obj.error) # Improper account number tests: for accnt in improper_account_numbers: logger.info('Testing IMPROPER Account Number: {}'.format(accnt)) arn_obj = ARN(accnt) self.assertTrue(arn_obj.error)
def test_from_arn(self): proper_arns = [ "events.amazonaws.com", "cloudtrail.amazonaws.com", "arn:aws:iam::012345678910:root", "arn:aws:iam::012345678910:role/SomeTestRoleForTesting", "arn:aws:iam::012345678910:instance-profile/SomeTestInstanceProfileForTesting", "arn:aws:iam::012345678910:role/*", "arn:aws:iam::012345678910:role/SomeTestRole*", "arn:aws:s3:::some-s3-bucket", "arn:aws:s3:*:*:some-s3-bucket", "arn:aws:s3:::some-s3-bucket/some/path/within/the/bucket" "arn:aws:s3:::some-s3-bucket/*", "arn:aws:ec2:us-west-2:012345678910:instance/*", "arn:aws:ec2:ap-northeast-1:012345678910:security-group/*", "arn:aws-cn:ec2:ap-northeast-1:012345678910:security-group/*", "arn:aws-us-gov:ec2:gov-west-1:012345678910:instance/*", "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXXXXXXXXXXXXX", "arn:aws:iam::aws:policy/AlexaForBusinessDeviceSetup", ] # Proper ARN Tests: for arn in proper_arns: logger.info("Testing Proper ARN: {}".format(arn)) arn_obj = ARN(arn) self.assertFalse(arn_obj.error) if "root" in arn: self.assertTrue(arn_obj.root) else: self.assertFalse(arn_obj.root) if ".amazonaws.com" in arn: self.assertTrue(arn_obj.service) else: self.assertFalse(arn_obj.service) bad_arns = [ "arn:aws:iam::012345678910", "arn:aws:iam::012345678910:", "*", "arn:s3::::", "arn:arn:arn:arn:arn:arn", ] # Improper ARN Tests: for arn in bad_arns: logger.info("Testing IMPROPER ARN: {}".format(arn)) arn_obj = ARN(arn) self.assertTrue(arn_obj.error)
def _arn_internet_accessible(self, arn_input): if "*" == arn_input: return True arn = ARN(arn_input) if arn.error: logger.warning("Auditor could not parse ARN {arn}.".format(arn=arn_input)) return "*" in arn_input if arn.tech == "s3": # S3 ARNs typically don't have account numbers. return False if not arn.account_number and not arn.service: logger.warning( "Auditor could not parse Account Number from ARN {arn}.".format( arn=arn_input ) ) return True if arn.account_number == "*": return True return False
def test_from_arn(self): proper_arns = [ 'events.amazonaws.com', 'cloudtrail.amazonaws.com', 'arn:aws:iam::012345678910:root', 'arn:aws:iam::012345678910:role/SomeTestRoleForTesting', 'arn:aws:iam::012345678910:instance-profile/SomeTestInstanceProfileForTesting', 'arn:aws:iam::012345678910:role/*', 'arn:aws:iam::012345678910:role/SomeTestRole*', 'arn:aws:s3:::some-s3-bucket', 'arn:aws:s3:*:*:some-s3-bucket', 'arn:aws:s3:::some-s3-bucket/some/path/within/the/bucket' 'arn:aws:s3:::some-s3-bucket/*', 'arn:aws:ec2:us-west-2:012345678910:instance/*', 'arn:aws:ec2:ap-northeast-1:012345678910:security-group/*', 'arn:aws-cn:ec2:ap-northeast-1:012345678910:security-group/*', 'arn:aws-us-gov:ec2:gov-west-1:012345678910:instance/*', 'arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXXXXXXXXXXXXX' ] # Proper ARN Tests: for arn in proper_arns: logger.info('Testing Proper ARN: {}'.format(arn)) arn_obj = ARN(arn) self.assertFalse(arn_obj.error) if "root" in arn: self.assertTrue(arn_obj.root) else: self.assertFalse(arn_obj.root) if ".amazonaws.com" in arn: self.assertTrue(arn_obj.service) else: self.assertFalse(arn_obj.service) bad_arns = [ 'arn:aws:iam::012345678910', 'arn:aws:iam::012345678910:', '*', 'arn:s3::::', "arn:arn:arn:arn:arn:arn" ] # Improper ARN Tests: for arn in bad_arns: logger.info('Testing IMPROPER ARN: {}'.format(arn)) arn_obj = ARN(arn) self.assertTrue(arn_obj.error)
def inspect_entity_arn(self, entity, same, item): arn_input = entity.value if arn_input == '*': return set(['UNKNOWN']) arn = ARN(arn_input) if arn.error: self.record_arn_parse_issue(item, arn_input) if arn.tech == 's3': return self.inspect_entity_s3(entity, arn.name, same) return set([self.inspect_entity_account(entity, arn.account_number, same)])
def check_root_cross_account(self, item): policies = self.load_resource_policies(item) for policy in policies: for statement in policy.statements: if statement.effect != 'Allow': continue for who in statement.whos_allowed(): if who.category not in ['arn', 'principal']: continue if who.value == '*': continue arn = ARN(who.value) entity = Entity.from_tuple(who) if arn.root and self.inspect_entity(entity, item).intersection(set(['FRIENDLY', 'THIRDPARTY', 'UNKNOWN'])): self.record_cross_account_root(item, entity, list(statement.actions))
def _remove_permissions_from_roles(permissions, role_filename, dynamo_table, config, hooks, commit=False): """Loads roles specified in file and calls _remove_permissions_from_role() for each one. Args: permissions (list<string>) role_filename (string) commit (bool) Returns: None """ roles = list() with open(role_filename, "r") as fd: roles = json.load(fd) for role_arn in tqdm(roles): arn = ARN(role_arn) if arn.error: LOGGER.error("INVALID ARN: {arn}".format(arn=role_arn)) return account_number = arn.account_number role_name = arn.name.split("/")[-1] role_id = find_role_in_cache(dynamo_table, account_number, role_name) role = Role.parse_obj(get_role_data(dynamo_table, role_id)) remove_permissions_from_role( account_number, permissions, role, role_id, dynamo_table, config, hooks, commit=commit, ) repokid.hooks.call_hooks(hooks, "AFTER_REPO", {"role": role})
def _remove_permissions_from_roles( permissions: List[str], role_filename: str, config: RepokidConfig, hooks: RepokidHooks, commit: bool = False, ) -> None: """Loads roles specified in file and calls _remove_permissions_from_role() for each one. Args: permissions (list<string>) role_filename (string) commit (bool) Returns: None """ with open(role_filename, "r") as fd: roles = json.load(fd) for role_arn in tqdm(roles): arn = ARN(role_arn) if arn.error: LOGGER.error("INVALID ARN: {arn}".format(arn=role_arn)) return account_number = arn.account_number role_name = arn.name.split("/")[-1] role_id = find_role_in_cache(role_name, account_number) role = Role(role_id=role_id) role.fetch() remove_permissions_from_role(account_number, permissions, role, config, hooks, commit=commit) repokid.hooks.call_hooks(hooks, "AFTER_REPO", {"role": role})
def check_unknown_cross_account(self, item): policies = self.load_resource_policies(item) for policy in policies: if policy.is_internet_accessible(): continue for statement in policy.statements: if statement.effect != 'Allow': continue for who in statement.whos_allowed(): if who.value == '*' and who.category == 'principal': continue # Ignore Service Principals if who.category == 'principal': arn = ARN(who.value) if arn.service: continue entity = Entity.from_tuple(who) if 'UNKNOWN' in self.inspect_entity(entity, item): self.record_unknown_access(item, entity, list(statement.actions))
def test_get_principal_role(self): self.assertEqual( self.trust_parser.get_trusted_principal_arns('role')[0].arn, ARN('arn:aws:iam::888222333221:role/AssumeInstanceRoleTA').arn)
def test_get_principal_account(self): # self.assertEqual("arn:aws:iam::123456789013:root",) self.assertEqual( self.trust_parser.get_trusted_principal_arns('root')[0].arn, ARN('arn:aws:iam::123456789013:root').arn)