Skip to content

Commit

Permalink
feat(mq): add mq_broker_not_publicly_accessible check (#5604)
Browse files Browse the repository at this point in the history
Co-authored-by: Sergio <[email protected]>
  • Loading branch information
sansns and MrCloudSec authored Nov 11, 2024
1 parent f231d8b commit 10766d7
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 0 deletions.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"Provider": "aws",
"CheckID": "mq_broker_not_publicly_accessible",
"CheckTitle": "MQ brokers should not be publicly accessible.",
"CheckType": [
"Software and Configuration Checks/Industry and Regulatory Standards/NIST 800-53 Controls"
],
"ServiceName": "mq",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:mq:region:account-id:broker:broker-id",
"Severity": "medium",
"ResourceType": "AwsAmazonMQBroker",
"Description": "Brokers created without public accessibility can't be accessed from outside of your VPC. This greatly reduces your broker's susceptibility to Distributed Denial of Service (DDoS) attacks from the public internet.",
"Risk": "Public Amazon MQ brokers can be accessed directly, outside of a Virtual Private Cloud (VPC), therefore every machine on the Internet can reach your brokers through their public endpoints and this can increase the opportunity for malicious activity such as cross-site scripting (XSS) and clickjacking attacks. ",
"RelatedUrl": "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/using-amazon-mq-securely.html#prefer-brokers-without-public-accessibility",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/MQ/publicly-accessible.html#",
"Terraform": ""
},
"Recommendation": {
"Text": "Ensure that the Amazon MQ brokers provisioned in your AWS account are not publicly accessible from the Internet in order to avoid exposing sensitive data and minimize security risks.",
"Url": "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/using-amazon-mq-securely.html#prefer-brokers-without-public-accessibility"
}
},
"Categories": [
"internet-exposed"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.mq.mq_client import mq_client


class mq_broker_not_publicly_accessible(Check):
def execute(self):
findings = []
for broker in mq_client.brokers.values():
report = Check_Report_AWS(self.metadata())
report.region = broker.region
report.resource_id = broker.id
report.resource_arn = broker.arn
report.resource_tags = broker.tags
report.status = "FAIL"
report.status_extended = f"MQ Broker {broker.name} is publicly accessible."

if not broker.publicly_accessible:
report.status = "PASS"
report.status_extended = (
f"MQ Broker {broker.name} is not publicly accessible."
)

findings.append(report)

return findings
4 changes: 4 additions & 0 deletions prowler/providers/aws/services/mq/mq_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ def _describe_broker(self, broker):
broker.audit_logging_enabled = describe_broker.get("Logs", {}).get(
"Audit", False
)
broker.publicly_accessible = describe_broker.get(
"PubliclyAccessible", False
)
broker.tags = [describe_broker.get("Tags", {})]

except Exception as error:
Expand Down Expand Up @@ -87,6 +90,7 @@ class Broker(BaseModel):
id: str
region: str
auto_minor_version_upgrade: bool = Field(default=False)
publicly_accessible: bool = Field(default=False)
general_logging_enabled: bool = Field(default=False)
audit_logging_enabled: bool = Field(default=False)
engine_type: EngineType = EngineType.ACTIVEMQ
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
from unittest import mock

from boto3 import client
from moto import mock_aws

from tests.providers.aws.utils import (
AWS_ACCOUNT_NUMBER,
AWS_REGION_US_EAST_1,
set_mocked_aws_provider,
)


class Test_mq_broker_not_publicly_accessible:
@mock_aws
def test_no_brokers(self):
from prowler.providers.aws.services.mq.mq_service import MQ

aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])

with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
), mock.patch(
"prowler.providers.aws.services.mq.mq_broker_not_publicly_accessible.mq_broker_not_publicly_accessible.mq_client",
new=MQ(aws_provider),
):
# Test Check
from prowler.providers.aws.services.mq.mq_broker_not_publicly_accessible.mq_broker_not_publicly_accessible import (
mq_broker_not_publicly_accessible,
)

check = mq_broker_not_publicly_accessible()
result = check.execute()

assert len(result) == 0

@mock_aws
def test_broker_publicly_accessible(self):
mq_client = client("mq", region_name=AWS_REGION_US_EAST_1)
broker_name = "test-broker"
broker_id = mq_client.create_broker(
BrokerName=broker_name,
EngineType="ACTIVEMQ",
EngineVersion="5.15.0",
HostInstanceType="mq.t2.micro",
Users=[
{
"Username": "admin",
"Password": "admin",
},
],
DeploymentMode="SINGLE_INSTANCE",
PubliclyAccessible=True,
AutoMinorVersionUpgrade=True,
)["BrokerId"]

from prowler.providers.aws.services.mq.mq_service import MQ

aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])

with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
), mock.patch(
"prowler.providers.aws.services.mq.mq_broker_not_publicly_accessible.mq_broker_not_publicly_accessible.mq_client",
new=MQ(aws_provider),
):
# Test Check
from prowler.providers.aws.services.mq.mq_broker_not_publicly_accessible.mq_broker_not_publicly_accessible import (
mq_broker_not_publicly_accessible,
)

check = mq_broker_not_publicly_accessible()
result = check.execute()

assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"MQ Broker {broker_name} is publicly accessible."
)
assert result[0].resource_id == broker_id
assert (
result[0].resource_arn
== f"arn:{aws_provider.identity.partition}:mq:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:broker:{broker_id}"
)
assert result[0].region == AWS_REGION_US_EAST_1

@mock_aws
def test_broker_not_publicly_accessible(self):
mq_client = client("mq", region_name=AWS_REGION_US_EAST_1)
broker_name = "test-broker"
broker_id = mq_client.create_broker(
BrokerName=broker_name,
EngineType="ACTIVEMQ",
EngineVersion="5.15.0",
HostInstanceType="mq.t2.micro",
Users=[
{
"Username": "admin",
"Password": "admin",
},
],
DeploymentMode="SINGLE_INSTANCE",
PubliclyAccessible=False,
AutoMinorVersionUpgrade=False,
)["BrokerId"]

from prowler.providers.aws.services.mq.mq_service import MQ

aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])

with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
), mock.patch(
"prowler.providers.aws.services.mq.mq_broker_not_publicly_accessible.mq_broker_not_publicly_accessible.mq_client",
new=MQ(aws_provider),
):
# Test Check
from prowler.providers.aws.services.mq.mq_broker_not_publicly_accessible.mq_broker_not_publicly_accessible import (
mq_broker_not_publicly_accessible,
)

check = mq_broker_not_publicly_accessible()
result = check.execute()

assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"MQ Broker {broker_name} is not publicly accessible."
)
assert result[0].resource_id == broker_id
assert (
result[0].resource_arn
== f"arn:{aws_provider.identity.partition}:mq:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:broker:{broker_id}"
)
assert result[0].region == AWS_REGION_US_EAST_1
1 change: 1 addition & 0 deletions tests/providers/aws/services/mq/mq_service_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,5 @@ def test_describe_broker(self):
assert mq.brokers[broker_arn].engine_type == EngineType.ACTIVEMQ
assert mq.brokers[broker_arn].deployment_mode == DeploymentMode.SINGLE_INSTANCE
assert mq.brokers[broker_arn].auto_minor_version_upgrade
assert mq.brokers[broker_arn].publicly_accessible
assert mq.brokers[broker_arn].tags == [{"key": "value"}]

0 comments on commit 10766d7

Please sign in to comment.