fix(security group): check if security groups are used by Lambda (#2944)

This commit is contained in:
Sergio Garcia
2023-10-19 12:13:24 +02:00
committed by GitHub
parent 54fe10ae86
commit 1ac22bddd6
10 changed files with 112 additions and 3 deletions

View File

@@ -50,6 +50,9 @@ class Lambda(AWSService):
self.functions[lambda_arn] = Function(
name=lambda_name,
arn=lambda_arn,
security_groups=function.get("VpcConfig", {}).get(
"SecurityGroupIds", []
),
region=regional_client.region,
)
if "Runtime" in function:
@@ -183,6 +186,7 @@ class URLConfig(BaseModel):
class Function(BaseModel):
name: str
arn: str
security_groups: list
runtime: Optional[str]
environment: dict = None
region: str

View File

@@ -1,4 +1,5 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.awslambda.awslambda_client import awslambda_client
from prowler.providers.aws.services.ec2.ec2_client import ec2_client
@@ -16,7 +17,11 @@ class ec2_securitygroup_not_used(Check):
report.resource_tags = security_group.tags
report.status = "PASS"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) it is being used."
if len(security_group.network_interfaces) == 0:
sg_in_lambda = False
for function in awslambda_client.functions.values():
if security_group.id in function.security_groups:
sg_in_lambda = True
if len(security_group.network_interfaces) == 0 and not sg_in_lambda:
report.status = "FAIL"
report.status_extended = f"Security group {security_group.name} ({security_group.id}) it is not being used."

View File

@@ -100,6 +100,7 @@ class Test_awslambda_function_invoke_api_operations_cloudtrail_logging_enabled:
lambda_client.functions = {
function_name: Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -164,6 +165,7 @@ class Test_awslambda_function_invoke_api_operations_cloudtrail_logging_enabled:
lambda_client.functions = {
function_name: Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -240,6 +242,7 @@ class Test_awslambda_function_invoke_api_operations_cloudtrail_logging_enabled:
lambda_client.functions = {
function_name: Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -317,6 +320,7 @@ class Test_awslambda_function_invoke_api_operations_cloudtrail_logging_enabled:
lambda_client.functions = {
function_name: Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,

View File

@@ -47,6 +47,7 @@ class Test_awslambda_function_no_secrets_in_code:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -95,6 +96,7 @@ class Test_awslambda_function_no_secrets_in_code:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,

View File

@@ -37,6 +37,7 @@ class Test_awslambda_function_no_secrets_in_variables:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -77,6 +78,7 @@ class Test_awslambda_function_no_secrets_in_variables:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -118,6 +120,7 @@ class Test_awslambda_function_no_secrets_in_variables:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,

View File

@@ -51,6 +51,7 @@ class Test_awslambda_function_not_publicly_accessible:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -106,6 +107,7 @@ class Test_awslambda_function_not_publicly_accessible:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -161,6 +163,7 @@ class Test_awslambda_function_not_publicly_accessible:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,

View File

@@ -41,6 +41,7 @@ class Test_awslambda_function_url_cors_policy:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -85,6 +86,7 @@ class Test_awslambda_function_url_cors_policy:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -129,6 +131,7 @@ class Test_awslambda_function_url_cors_policy:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,

View File

@@ -41,6 +41,7 @@ class Test_awslambda_function_url_public:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -85,6 +86,7 @@ class Test_awslambda_function_url_public:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,

View File

@@ -36,6 +36,7 @@ class Test_awslambda_function_using_supported_runtimes:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -93,6 +94,7 @@ class Test_awslambda_function_using_supported_runtimes:
lambda_client.functions = {
"function_name": Function(
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
runtime=function_runtime,
@@ -148,7 +150,10 @@ class Test_awslambda_function_using_supported_runtimes:
)
lambda_client.functions = {
"function_name": Function(
name=function_name, arn=function_arn, region=AWS_REGION
name=function_name,
security_groups=[],
arn=function_arn,
region=AWS_REGION,
)
}

View File

@@ -2,7 +2,7 @@ from re import search
from unittest import mock
from boto3 import client, resource, session
from moto import mock_ec2
from moto import mock_ec2, mock_iam, mock_lambda
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
from prowler.providers.common.models import Audit_Metadata
@@ -169,3 +169,81 @@ class Test_ec2_securitygroup_not_used:
assert result[0].resource_id == sg.id
assert result[0].resource_details == sg_name
assert result[0].resource_tags == []
@mock_ec2
@mock_lambda
@mock_iam
def test_ec2_used_default_sg_by_lambda(self):
# Create EC2 Mocked Resources
ec2 = resource("ec2", AWS_REGION)
ec2_client = client("ec2", region_name=AWS_REGION)
vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"]
sg_name = "test-sg"
sg = ec2.create_security_group(
GroupName=sg_name, Description="test", VpcId=vpc_id
)
subnet = ec2.create_subnet(VpcId=vpc_id, CidrBlock="10.0.0.0/18")
subnet.create_network_interface(Groups=[sg.id])
iam_client = client("iam", region_name=AWS_REGION)
iam_role = iam_client.create_role(
RoleName="my-role",
AssumeRolePolicyDocument="some policy",
Path="/my-path/",
)["Role"]["Arn"]
lambda_client = client("lambda", AWS_REGION)
lambda_client.create_function(
FunctionName="test-function",
Runtime="python3.11",
Role=iam_role,
Handler="lambda_function.lambda_handler",
Code={
"ImageUri": f"{AWS_ACCOUNT_NUMBER}.dkr.ecr.us-east-1.amazonaws.com/testlambdaecr:prod"
},
Description="test lambda function",
Timeout=3,
MemorySize=128,
Publish=True,
VpcConfig={
"SecurityGroupIds": [sg.id],
"SubnetIds": [subnet.id],
},
)
from prowler.providers.aws.services.ec2.ec2_service import EC2
current_audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=current_audit_info,
), mock.patch(
"prowler.providers.aws.services.ec2.ec2_securitygroup_not_used.ec2_securitygroup_not_used.ec2_client",
new=EC2(current_audit_info),
):
# Test Check
from prowler.providers.aws.services.ec2.ec2_securitygroup_not_used.ec2_securitygroup_not_used import (
ec2_securitygroup_not_used,
)
check = ec2_securitygroup_not_used()
result = check.execute()
# One custom sg
assert len(result) == 1
assert result[0].status == "PASS"
assert result[0].region == AWS_REGION
assert (
result[0].status_extended
== f"Security group {sg_name} ({sg.id}) it is being used."
)
assert search(
"it is being used",
result[0].status_extended,
)
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{sg.id}"
)
assert result[0].resource_id == sg.id
assert result[0].resource_details == sg_name
assert result[0].resource_tags == []