示例#1
0
 def test_public(self):
     arn = 'arn:aws:execute-api:eu-west-1:0:id/stage/method/path'
     expected = {
         'level': 'high',
         'text': 'Service is publicly accessible due to missing Resource-based policy'
     }
     self.assertEqual(expected, next(Public(APIGateway(arn)).audit()))
示例#2
0
 def test_public_ok(self):
     expected = StopIteration
     obj = APIGateway(
         "arn:aws:execute-api:eu-west-1:0:id/stage/method/path")
     obj.policy = {"test": "test"}
     with self.assertRaises(expected):
         next(Public(obj).audit())
示例#3
0
    def test_public(self):
        obj = APIGateway(
            "arn:aws:execute-api:eu-west-1:0:id/stage/method/path")

        # No policy and API Key not required
        expected = {
            "level":
            "high",
            "text":
            "Service is publicly accessible due to missing Resource-based policy",
        }
        obj.policy = {}
        obj.resources = [{
            "id": "0",
            "method": "GET",
            "path": "/",
            "apiKeyRequired": False,
            "authorizationType": "NONE",
        }]
        self.assertEqual(expected, next(Public(obj).audit()))

        # No policy and API Key required
        expected = StopIteration
        obj.resources = [{
            "id": "0",
            "method": "GET",
            "path": "/",
            "apiKeyRequired": True,
            "authorizationType": "NONE",
        }]
        with self.assertRaises(expected):
            next(Public(obj).audit())

        # No policy and Authorization Type set
        expected = StopIteration
        obj.resources = [{
            "id": "0",
            "method": "GET",
            "path": "/",
            "apiKeyRequired": False,
            "authorizationType": "AWS_IAM",
        }]
        with self.assertRaises(expected):
            next(Public(obj).audit())
示例#4
0
    def test_public(self):
        obj = APIGateway(
            'arn:aws:execute-api:eu-west-1:0:id/stage/method/path')

        # No policy and API Key not required
        expected = {
            'level':
            'high',
            'text':
            'Service is publicly accessible due to missing Resource-based policy'
        }
        obj.policy = {}
        obj.resources = [{
            'id': '0',
            'method': 'GET',
            'path': '/',
            'apiKeyRequired': False,
            'authorizationType': 'NONE'
        }]
        self.assertEqual(expected, next(Public(obj).audit()))

        # No policy and API Key required
        expected = StopIteration
        obj.resources = [{
            'id': '0',
            'method': 'GET',
            'path': '/',
            'apiKeyRequired': True,
            'authorizationType': 'NONE'
        }]
        with self.assertRaises(expected):
            next(Public(obj).audit())

        # No policy and Authorization Type set
        expected = StopIteration
        obj.resources = [{
            'id': '0',
            'method': 'GET',
            'path': '/',
            'apiKeyRequired': False,
            'authorizationType': 'AWS_IAM'
        }]
        with self.assertRaises(expected):
            next(Public(obj).audit())
示例#5
0
    def scan(self):
        '''
        Scan Lambda report for vulnerabilities
        and provide recommendations.
        '''
        # Audit Function policy
        if not self.report['policy']['function']:
            self.track(self.report['arn'], {
                'level': 'info',
                'text': 'Function policy is not defined'
            })
        else:
            if 'Statement' in self.report['policy']['function']:
                for statement in self.report['policy']['function'][
                        'Statement']:
                    for _ in PolicyStatement(statement).audit():
                        self.track(self.report['arn'], _)

        # Audit Execution role policy
        if not len(self.report['policy']['role']['policies']):
            self.track(self.report['arn'], {
                'level': 'info',
                'text': 'Execution Role policy is not defined'
            })
        else:
            for policy in self.report['policy']['role']['policies']:
                if 'Statement' in policy['document']:
                    for statement in policy['document']['Statement']:
                        for _ in PolicyStatement(statement,
                                                 policy=policy).audit():
                            self.track(self.report['role'], _)

        # Audit Resources
        if 'logs' not in self.report['resources']['services']:
            self.track(
                self.report['arn'], {
                    'level':
                    'low',
                    'text':
                    'Function activity is not monitored by CloudWatch due to missing logs permissions'
                })

        # Audit Triggers and Resources
        items = list(
            set(
                list(self.report['triggers']['items'].keys()) +
                list(self.report['resources']['items'].keys())))
        for arn in items:
            if arn == '*':
                continue

            arn = arnparse(arn)
            if arn.resource in ['*', '']:
                continue

            self.item = None
            if arn.service == 's3':
                if arn.resource_type:  # S3 object path
                    continue
                self.item = S3(arn.full,
                               profile=self.profile,
                               access_key_id=self.access_key_id,
                               secret_access_key=self.secret_access_key)
                for _ in AccessControlList(self.item.acl).audit():
                    self.track(arn.full, _)
                for _ in Encryption(self.item).audit():
                    self.track(arn.full, _)
            elif arn.service == 'sqs':
                self.item = SQS(arn.full,
                                profile=self.profile,
                                access_key_id=self.access_key_id,
                                secret_access_key=self.secret_access_key)
            elif arn.service == 'sns':
                self.item = SNS(arn.full,
                                profile=self.profile,
                                access_key_id=self.access_key_id,
                                secret_access_key=self.secret_access_key)
            elif arn.service == 'apigateway':
                self.item = APIGateway(
                    arn.full,
                    profile=self.profile,
                    access_key_id=self.access_key_id,
                    secret_access_key=self.secret_access_key)
            elif arn.service == 'dynamodb':
                self.item = DynamoDB(arn.full,
                                     profile=self.profile,
                                     access_key_id=self.access_key_id,
                                     secret_access_key=self.secret_access_key)

            if self.item:
                # Audit item Resource-based Policy
                if 'Statement' in self.item.policy:
                    for statement in self.item.policy['Statement']:
                        for _ in PolicyStatement(statement).audit():
                            self.track(arn.full, _)
                # If policy is missing, the the service is public
                else:
                    for _ in Public(self.item).audit():
                        self.track(arn.full, _)

        # SonarQube
        if self.args.sonarqube:
            self.scan_sonarqube(arn, self.report['codeURL'],
                                self.report['runtime'])
            for layer in self.report['layers']:
                self.scan_sonarqube(arn, layer['codeURL'],
                                    self.report['runtime'])

        # Sort findings by level
        sorted_items = []
        for sort in ['high', 'medium', 'low', 'info']:
            for item in self.security['items']:
                if item['level'] == sort:
                    if item not in sorted_items:
                        sorted_items.append(item)
        self.security['items'] = sorted_items
示例#6
0
    def scan(self):
        """
        Scan Lambda report for vulnerabilities
        and provide recommendations.
        """
        # Audit Function policy
        if not self.report["policy"]["function"]:
            self.track(
                self.report["arn"],
                {
                    "level": "info",
                    "text": "Function policy is not defined"
                },
            )
        else:
            if "Statement" in self.report["policy"]["function"]:
                for statement in self.report["policy"]["function"][
                        "Statement"]:
                    for _ in PolicyStatement(statement).audit():
                        self.track(self.report["arn"], _)

        # Audit Execution role policy
        if not len(self.report["policy"]["role"]["policies"]):
            self.track(
                self.report["arn"],
                {
                    "level": "info",
                    "text": "Execution Role policy is not defined"
                },
            )
        else:
            for policy in self.report["policy"]["role"]["policies"]:
                if "Statement" in policy["document"]:
                    for statement in policy["document"]["Statement"]:
                        for _ in PolicyStatement(statement,
                                                 policy=policy).audit():
                            self.track(self.report["role"], _)

        # Audit KMS
        if "kms" in self.report:
            self.item = KMS(
                self.report["kms"],
                profile=self.profile,
                access_key_id=self.access_key_id,
                secret_access_key=self.secret_access_key,
            )
            if not self.item.rotation:
                self.track(
                    self.report["kms"],
                    {
                        "level":
                        "medium",
                        "text":
                        ("Automatic rotation of key material is disabled\n"
                         "https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html"
                         ),
                    },
                )
            for _, policy in self.item.policies.items():
                self.audit_policy_statements(self.item.arn, policy)

        # Audit Resources
        if "logs" not in self.report["resources"]["services"]:
            self.track(
                self.report["arn"],
                {
                    "level":
                    "low",
                    "text":
                    "Function activity is not monitored by CloudWatch due to missing logs permissions",
                },
            )

        # Audit Triggers and Resources
        items = list(
            set(
                list(self.report["triggers"]["items"].keys()) +
                list(self.report["resources"]["items"].keys())))
        for arn in items:
            if arn == "*":
                continue

            arn = arnparse(arn)
            if arn.resource in ["*", ""]:
                continue

            self.item = None
            if arn.service == "s3":
                if arn.resource_type:  # S3 object path
                    continue
                self.item = S3(
                    arn.full,
                    profile=self.profile,
                    access_key_id=self.access_key_id,
                    secret_access_key=self.secret_access_key,
                )
                for _ in AccessControlList(self.item.acl).audit():
                    self.track(arn.full, _)
                for _ in Encryption(self.item).audit():
                    self.track(arn.full, _)
            elif arn.service == "sqs":
                self.item = SQS(
                    arn.full,
                    profile=self.profile,
                    access_key_id=self.access_key_id,
                    secret_access_key=self.secret_access_key,
                )
            elif arn.service == "sns":
                self.item = SNS(
                    arn.full,
                    profile=self.profile,
                    access_key_id=self.access_key_id,
                    secret_access_key=self.secret_access_key,
                )
            elif arn.service == "apigateway":
                self.item = APIGateway(
                    arn.full,
                    profile=self.profile,
                    access_key_id=self.access_key_id,
                    secret_access_key=self.secret_access_key,
                )
            elif arn.service == "dynamodb":
                self.item = DynamoDB(
                    arn.full,
                    profile=self.profile,
                    access_key_id=self.access_key_id,
                    secret_access_key=self.secret_access_key,
                )
            elif arn.service == "kms":
                self.item = KMS(
                    arn.full,
                    profile=self.profile,
                    access_key_id=self.access_key_id,
                    secret_access_key=self.secret_access_key,
                )

            if self.item:
                if type(self.item) == KMS:
                    # Audit KMS Policies
                    for _, policy in self.item.policies.items():
                        self.audit_policy_statements(self.item.arn, policy)
                else:
                    # Audit item Resource-based Policy
                    self.audit_policy_statements(self.item.arn,
                                                 self.item.policy)
                    # If policy is missing, then the service is public
                    for _ in Public(self.item).audit():
                        self.track(arn.full, _)

        # SonarQube
        if self.args.sonarqube:
            self.scan_sonarqube(arn, self.report["codeURL"],
                                self.report["runtime"])
            for layer in self.report["layers"]:
                self.scan_sonarqube(arn, layer["codeURL"],
                                    self.report["runtime"])

        # Sort findings by level
        sorted_items = []
        for sort in ["high", "medium", "low", "info"]:
            for item in self.security["items"]:
                if item["level"] == sort:
                    if item not in sorted_items:
                        sorted_items.append(item)
        self.security["items"] = sorted_items