fix(elbv2): Handle post-quantum (PQ) TLS policies (#10219)

This commit is contained in:
Pepe Fagoaga
2026-03-03 09:18:00 +00:00
committed by GitHub
parent fa93cabc0b
commit 9c2cb5efa8
4 changed files with 119 additions and 2 deletions
+1 -1
View File
@@ -122,7 +122,7 @@ jobs:
"wafv2": ["cognito", "elbv2"],
}
changed_raw = """${STEPS_CHANGED_AWS_OUTPUTS_ALL_CHANGED_FILES}"""
changed_raw = os.environ.get("STEPS_CHANGED_AWS_OUTPUTS_ALL_CHANGED_FILES", "")
# all_changed_files is space-separated, not newline-separated
# Strip leading "./" if present for consistent path handling
changed_files = [Path(f.lstrip("./")) for f in changed_raw.split() if f]
+1 -1
View File
@@ -72,7 +72,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- Handle serialization errors in OCSF output for non-serializable resource metadata [(#10129)](https://github.com/prowler-cloud/prowler/pull/10129)
- Respect `AWS_ENDPOINT_URL` environment variable for STS session creation [(#10228)](https://github.com/prowler-cloud/prowler/pull/10228)
- Help text and typos in CLI flags [(#10040)](https://github.com/prowler-cloud/prowler/pull/10040)
- `elbv2_insecure_ssl_ciphers` false positive on AWS post-quantum (PQ) TLS policies like `ELBSecurityPolicy-TLS13-1-2-PQ-2025-09` [(#10219)](https://github.com/prowler-cloud/prowler/pull/10219)
### 🔐 Security
@@ -16,6 +16,19 @@ class elbv2_insecure_ssl_ciphers(Check):
"ELBSecurityPolicy-TLS13-1-2-Res-2021-06",
"ELBSecurityPolicy-TLS13-1-2-Ext1-2021-06",
"ELBSecurityPolicy-TLS13-1-2-Ext2-2021-06",
# AWS post-quantum (PQ) TLS policies (TLS 1.2+ minimum)
"ELBSecurityPolicy-TLS13-1-2-Ext1-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Ext2-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-3-PQ-2025-09",
# AWS FIPS post-quantum (PQ) TLS policies (TLS 1.2+ minimum)
"ELBSecurityPolicy-TLS13-1-2-Ext0-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Ext1-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Ext2-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Res-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09",
]
for lb in elbv2_client.loadbalancersv2.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=lb)
@@ -1,5 +1,6 @@
from unittest import mock
import pytest
from boto3 import client, resource
from moto import mock_aws
@@ -216,3 +217,106 @@ class Test_elbv2_insecure_ssl_ciphers:
)
assert result[0].resource_id == "my-lb"
assert result[0].resource_arn == lb["LoadBalancerArn"]
@pytest.mark.parametrize(
"ssl_policy",
[
"ELBSecurityPolicy-TLS13-1-3-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Ext1-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Ext2-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Res-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Ext0-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Ext1-FIPS-PQ-2025-09",
"ELBSecurityPolicy-TLS13-1-2-Ext2-FIPS-PQ-2025-09",
],
)
@mock_aws
def test_elbv2_listener_with_pq_tls_policy(self, ssl_policy):
conn = client("elbv2", region_name=AWS_REGION_EU_WEST_1)
ec2 = resource("ec2", region_name=AWS_REGION_EU_WEST_1)
security_group = ec2.create_security_group(
GroupName="a-security-group", Description="First One"
)
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
subnet1 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock="172.28.7.192/26",
AvailabilityZone=AWS_REGION_EU_WEST_1_AZA,
)
subnet2 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock="172.28.7.0/26",
AvailabilityZone=AWS_REGION_EU_WEST_1_AZB,
)
lb = conn.create_load_balancer(
Name="my-lb",
Subnets=[subnet1.id, subnet2.id],
SecurityGroups=[security_group.id],
Scheme="internal",
Type="application",
)["LoadBalancers"][0]
response = conn.create_target_group(
Name="a-target",
Protocol="HTTP",
Port=8080,
VpcId=vpc.id,
HealthCheckProtocol="HTTP",
HealthCheckPort="8080",
HealthCheckPath="/",
HealthCheckIntervalSeconds=5,
HealthCheckTimeoutSeconds=3,
HealthyThresholdCount=5,
UnhealthyThresholdCount=2,
Matcher={"HttpCode": "200"},
)
target_group = response.get("TargetGroups")[0]
target_group_arn = target_group["TargetGroupArn"]
conn.create_listener(
LoadBalancerArn=lb["LoadBalancerArn"],
Protocol="HTTPS",
Port=443,
SslPolicy=ssl_policy,
DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
)
from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1]
),
),
mock.patch(
"prowler.providers.aws.services.elbv2.elbv2_insecure_ssl_ciphers.elbv2_insecure_ssl_ciphers.elbv2_client",
new=ELBv2(
set_mocked_aws_provider(
[AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1],
create_default_organization=False,
)
),
),
):
from prowler.providers.aws.services.elbv2.elbv2_insecure_ssl_ciphers.elbv2_insecure_ssl_ciphers import (
elbv2_insecure_ssl_ciphers,
)
check = elbv2_insecure_ssl_ciphers()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "ELBv2 my-lb does not have insecure SSL protocols or ciphers."
)
assert result[0].resource_id == "my-lb"
assert result[0].resource_arn == lb["LoadBalancerArn"]