From 7b12fec0926348751b576b3bc298a1623023a846 Mon Sep 17 00:00:00 2001 From: Garrett Beatty Date: Fri, 14 Aug 2026 11:03:32 -0400 Subject: [PATCH] Restrict ALB integration-test security group to the test runner's IP The ALB integration test provisioned an internet-facing ALB with a security group open to 0.0.0.0/0 on port 80 and no authentication. DyePack's EC2IPAuthentication scanner flags this publicly accessible endpoint, which has required a standing AppSec exception for the test accounts. Add an AllowedCidr template parameter (no default, fails closed) and point the security group ingress at it. DeploymentScript.ps1 resolves the runner's public egress IP and passes it as AllowedCidr=/32, so the ALB stays reachable by the test client but not by DyePack's scanners. The ALB remains internet-facing so the existing test, which calls the public DNS from outside the VPC, is unchanged. --- .../DeploymentScript.ps1 | 20 ++++++++++++++++++- .../TestServerlessApp.ALB/serverless.template | 12 ++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Libraries/test/TestServerlessApp.ALB.IntegrationTests/DeploymentScript.ps1 b/Libraries/test/TestServerlessApp.ALB.IntegrationTests/DeploymentScript.ps1 index f5e9e463d..e651d26a6 100644 --- a/Libraries/test/TestServerlessApp.ALB.IntegrationTests/DeploymentScript.ps1 +++ b/Libraries/test/TestServerlessApp.ALB.IntegrationTests/DeploymentScript.ps1 @@ -85,8 +85,26 @@ try } dotnet restore + + # Resolve this runner's public egress IP so the test ALB's security group only admits us. + # The ALB stays internet-facing (the test client reaches it over public DNS), but locking + # ingress to a single /32 means it is not reachable by DyePack's scanners, which avoids + # EC2IPAuthentication findings on this short-lived integration ALB. Fail closed if we can't + # determine the IP rather than falling back to 0.0.0.0/0. + $myIp = $null + for ($i = 1; $i -le 3; $i++) + { + try { $myIp = (Invoke-RestMethod -Uri 'https://checkip.amazonaws.com' -TimeoutSec 10).Trim(); break } + catch { Write-Host "Attempt $i to resolve public IP failed: $_"; Start-Sleep -Seconds ($i * 2) } + } + if ([string]::IsNullOrEmpty($myIp) -or $myIp -notmatch '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') + { + throw "Could not resolve a valid public IP for the ALB security group; aborting to avoid opening the ALB to the internet." + } + Write-Host "Restricting test ALB ingress to runner IP $myIp/32" + Write-Host "Creating CloudFormation Stack $identifier, Architecture $arch" - dotnet lambda deploy-serverless + dotnet lambda deploy-serverless --template-parameters "AllowedCidr=$myIp/32" if (!$?) { Write-Host "Deployment failed. Fetching CloudFormation stack events for debugging..." diff --git a/Libraries/test/TestServerlessApp.ALB/serverless.template b/Libraries/test/TestServerlessApp.ALB/serverless.template index 83604a87f..f6c9c6b01 100644 --- a/Libraries/test/TestServerlessApp.ALB/serverless.template +++ b/Libraries/test/TestServerlessApp.ALB/serverless.template @@ -2,6 +2,14 @@ "AWSTemplateFormatVersion": "2010-09-09", "Transform": "AWS::Serverless-2016-10-31", "Description": "ALB Integration Test Stack - VPC and ALB infrastructure for testing Lambda ALB annotations This template is partially managed by Amazon.Lambda.Annotations (v2.4.0.0).", + "Parameters": { + "AllowedCidr": { + "Type": "String", + "Description": "CIDR allowed to reach the test ALB on port 80. The deployment script sets this to the test runner's public IP (/32) so this short-lived integration ALB is never open to the internet, which avoids DyePack EC2IPAuthentication findings. Intentionally has no default so a deploy without it fails closed rather than opening the ALB to 0.0.0.0/0.", + "AllowedPattern": "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/\\d{1,2}$", + "ConstraintDescription": "Must be a valid IPv4 CIDR, e.g. 203.0.113.10/32" + } + }, "Resources": { "ALBTestVPC": { "Type": "AWS::EC2::VPC", @@ -122,7 +130,9 @@ "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, - "CidrIp": "0.0.0.0/0" + "CidrIp": { + "Ref": "AllowedCidr" + } } ] }