Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(autoscaling_find_secrets_ec2_launch_configuration): Fix UnicodeDecodeError #2870

Merged
merged 3 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import tempfile
import zlib
from base64 import b64decode

from detect_secrets import SecretsCollection
Expand All @@ -22,7 +23,14 @@ def execute(self):

if configuration.user_data:
temp_user_data_file = tempfile.NamedTemporaryFile(delete=False)
user_data = b64decode(configuration.user_data).decode("utf-8")
user_data = b64decode(configuration.user_data)

if user_data[0:2] == b"\x1f\x8b": # GZIP magic number
user_data = zlib.decompress(user_data, zlib.MAX_WBITS | 32).decode(
"utf-8"
)
else:
user_data = user_data.decode("utf-8")

temp_user_data_file.write(
bytes(user_data, encoding="raw_unicode_escape")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from os import path
from pathlib import Path
from unittest import mock

from boto3 import client, session
Expand All @@ -9,6 +11,9 @@
AWS_REGION = "us-east-1"
AWS_ACCOUNT_NUMBER = "123456789012"

ACTUAL_DIRECTORY = Path(path.dirname(path.realpath(__file__)))
FIXTURES_DIR_NAME = "fixtures"


class Test_autoscaling_find_secrets_ec2_launch_configuration:
def set_mocked_audit_info(self):
Expand Down Expand Up @@ -168,7 +173,7 @@ def test_one_autoscaling_with_secrets(self):
def test_one_autoscaling_file_with_secrets(self):
# Include launch_configurations to check
f = open(
"prowler/providers/aws/services/autoscaling/autoscaling_find_secrets_ec2_launch_configuration/fixtures/fixture",
f"{ACTUAL_DIRECTORY}/{FIXTURES_DIR_NAME}/fixture",
"r",
)
secrets = f.read()
Expand Down Expand Up @@ -261,3 +266,56 @@ def test_one_launch_configurations_without_user_data(self):
assert result[0].resource_id == launch_configuration_name
assert result[0].resource_arn == launch_configuration_arn
assert result[0].region == AWS_REGION

@mock_autoscaling
def test_one_autoscaling_file_with_secrets_gzip(self):
# Include launch_configurations to check
f = open(
f"{ACTUAL_DIRECTORY}/{FIXTURES_DIR_NAME}/fixture.gz",
"rb",
)

secrets = f.read()
launch_configuration_name = "tester"
autoscaling_client = client("autoscaling", region_name=AWS_REGION)
autoscaling_client.create_launch_configuration(
LaunchConfigurationName="tester",
ImageId="ami-12c6146b",
InstanceType="t1.micro",
KeyName="the_keys",
SecurityGroups=["default", "default2"],
UserData=secrets,
)
launch_configuration_arn = autoscaling_client.describe_launch_configurations(
LaunchConfigurationNames=[launch_configuration_name]
)["LaunchConfigurations"][0]["LaunchConfigurationARN"]

from prowler.providers.aws.services.autoscaling.autoscaling_service import (
AutoScaling,
)

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.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_client",
new=AutoScaling(current_audit_info),
):
from prowler.providers.aws.services.autoscaling.autoscaling_find_secrets_ec2_launch_configuration.autoscaling_find_secrets_ec2_launch_configuration import (
autoscaling_find_secrets_ec2_launch_configuration,
)

check = autoscaling_find_secrets_ec2_launch_configuration()
result = check.execute()

assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Potential secret found in autoscaling {launch_configuration_name} User Data."
)
assert result[0].resource_id == launch_configuration_name
assert result[0].resource_arn == launch_configuration_arn
assert result[0].region == AWS_REGION
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from os import path
from pathlib import Path
from unittest import mock

from boto3 import resource, session
Expand All @@ -10,6 +12,9 @@
EXAMPLE_AMI_ID = "ami-12c6146b"
AWS_ACCOUNT_NUMBER = "123456789012"

ACTUAL_DIRECTORY = Path(path.dirname(path.realpath(__file__)))
FIXTURES_DIR_NAME = "fixtures"


class Test_ec2_instance_secrets_user_data:
def set_mocked_audit_info(self):
Expand Down Expand Up @@ -154,7 +159,7 @@ def test_one_ec2_with_secrets(self):
def test_one_ec2_file_with_secrets(self):
# Include launch_configurations to check
f = open(
"prowler/providers/aws/services/ec2/ec2_instance_secrets_user_data/fixtures/fixture",
f"{ACTUAL_DIRECTORY}/{FIXTURES_DIR_NAME}/fixture",
"r",
)
secrets = f.read()
Expand Down Expand Up @@ -233,3 +238,48 @@ def test_one_launch_configurations_without_user_data(self):
)
assert result[0].resource_tags is None
assert result[0].region == AWS_REGION

@mock_ec2
def test_one_ec2_file_with_secrets_gzip(self):
# Include launch_configurations to check
f = open(
f"{ACTUAL_DIRECTORY}/{FIXTURES_DIR_NAME}/fixture.gz",
"rb",
)
secrets = f.read()
ec2 = resource("ec2", region_name=AWS_REGION)
instance = ec2.create_instances(
ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, UserData=secrets
)[0]

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_instance_secrets_user_data.ec2_instance_secrets_user_data.ec2_client",
new=EC2(current_audit_info),
):
from prowler.providers.aws.services.ec2.ec2_instance_secrets_user_data.ec2_instance_secrets_user_data import (
ec2_instance_secrets_user_data,
)

check = ec2_instance_secrets_user_data()
result = check.execute()

assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Potential secret found in EC2 instance {instance.id} User Data -> Secret Keyword on line 1, Hex High Entropy String on line 3, Secret Keyword on line 3, Secret Keyword on line 4."
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)
assert result[0].resource_tags is None
assert result[0].region == AWS_REGION
Binary file not shown.