diff --git a/apps/api/src/cloud-security/plan-normalizer-aws-edge-cases.spec.ts b/apps/api/src/cloud-security/plan-normalizer-aws-edge-cases.spec.ts index 895d50e5d..eca6466aa 100644 --- a/apps/api/src/cloud-security/plan-normalizer-aws-edge-cases.spec.ts +++ b/apps/api/src/cloud-security/plan-normalizer-aws-edge-cases.spec.ts @@ -97,6 +97,36 @@ describe('normalizeFixPlan — AWS remediation edge cases', () => { expect(result.rollbackSteps[0].params.GroupId).toBe('sg-0123abc'); }); + it('backfills GroupId on EC2 security-group egress commands from the finding resource id', () => { + const ipPermissions = [ + { + IpProtocol: '-1', + IpRanges: [{ CidrIp: '0.0.0.0/0' }], + }, + ]; + const plan = makePlan({ + fixSteps: [ + makeStep({ + service: 'ec2', + command: 'RevokeSecurityGroupEgressCommand', + params: { IpPermissions: ipPermissions }, + }), + ], + rollbackSteps: [ + makeStep({ + service: 'ec2', + command: 'AuthorizeSecurityGroupEgressCommand', + params: { IpPermissions: ipPermissions }, + }), + ], + }); + + const result = normalizeFixPlan(plan, { resourceId: 'sg-0123abc' }); + + expect(result.fixSteps[0].params.GroupId).toBe('sg-0123abc'); + expect(result.rollbackSteps[0].params.GroupId).toBe('sg-0123abc'); + }); + it('does not overwrite an explicit security-group GroupName', () => { const plan = makePlan({ fixSteps: [ diff --git a/apps/api/src/cloud-security/plan-normalizer.ts b/apps/api/src/cloud-security/plan-normalizer.ts index c4f70b5e5..ea6c8e207 100644 --- a/apps/api/src/cloud-security/plan-normalizer.ts +++ b/apps/api/src/cloud-security/plan-normalizer.ts @@ -35,6 +35,8 @@ const IAM_LIKE_SERVICES = new Set(['iam', 'sts']); const EC2_SECURITY_GROUP_COMMANDS = new Set([ 'AuthorizeSecurityGroupIngressCommand', 'RevokeSecurityGroupIngressCommand', + 'AuthorizeSecurityGroupEgressCommand', + 'RevokeSecurityGroupEgressCommand', ]); const S3_ACL_COMMANDS = new Set(['PutBucketAclCommand']); const S3_ACL_PERMISSIONS = new Set(['s3:PutBucketAcl']);