Reviewed commit: be11bdcb5. Note: origin/main moved to 3e9660d06 during the review; re-verify against current main before changing code, since a finding may have been fixed or moved.
Blast radius: a template customers deploy into their own AWS accounts. This is not internal CI infrastructure. The affected stack grants irreversible multi-year spend authority in the customer's account, which is why this carries priority/p0 / severity/critical / impact/all-users rather than the priority/p1 / impact/internal used for our own deploy-identity findings.
Where
iac/federation/aws-target/cloudformation/template.yaml:42-50 (OIDCThumbprint parameter, default all-zeros, validated only as 40 hex characters)
iac/federation/aws-target/cloudformation/template.yaml:75-76 (where it is used)
iac/federation/aws-target/terraform/variables.tf:79-87 (the sibling guard that this template lacks)
What
The CloudFormation template accepts the all-zeros placeholder thumbprint for any issuer URL. Its only validation is an AllowedPattern requiring 40 hexadecimal characters, which the all-zeros string satisfies.
The Terraform sibling treats this as unacceptable and rejects the placeholder unless the issuer is one AWS validates natively (login.microsoftonline.com or accounts.google.com), with the reasoning recorded in the validation message:
the all-zeros value bypasses the CA-chain check entirely
Failure scenario
A customer points the CloudFormation template at a self-hosted or third-party OIDC issuer and leaves OIDCThumbprint at its default. AWS then performs no CA-chain validation on the issuer's TLS certificate. An attacker who can MITM or DNS-hijack the issuer's JWKS endpoint mints tokens that sts:AssumeRoleWithWebIdentity accepts, landing in a role that holds ec2:PurchaseReservedInstancesOffering, savingsplans:CreateSavingsPlan, and rds:PurchaseReservedDBInstancesOffering (template.yaml:96-149). The result is irreversible multi-year spend commitments in the customer's account.
The customer has no signal that anything is wrong: the stack deploys cleanly, onboarding reports success, and the difference between this and the Terraform path is invisible unless they read both.
Fix direction
Port the Terraform guard into the template. Either:
- add a
Condition that fails the deployment when OIDCThumbprint equals the all-zeros value and OIDCIssuerURL is not one of the AWS-natively-validated issuers (a Fn::If selecting a deliberately-invalid resource, or an AWS::CloudFormation::Init-style assertion), or
- add a Lambda-backed custom resource that validates the thumbprint against the issuer's live certificate chain and fails the stack on mismatch.
Whichever is chosen, the all-zeros default should be removed so a customer must make an explicit choice.
Related
Reviewed commit:
be11bdcb5. Note:origin/mainmoved to3e9660d06during the review; re-verify against currentmainbefore changing code, since a finding may have been fixed or moved.Blast radius: a template customers deploy into their own AWS accounts. This is not internal CI infrastructure. The affected stack grants irreversible multi-year spend authority in the customer's account, which is why this carries
priority/p0/severity/critical/impact/all-usersrather than thepriority/p1/impact/internalused for our own deploy-identity findings.Where
iac/federation/aws-target/cloudformation/template.yaml:42-50(OIDCThumbprintparameter, default all-zeros, validated only as 40 hex characters)iac/federation/aws-target/cloudformation/template.yaml:75-76(where it is used)iac/federation/aws-target/terraform/variables.tf:79-87(the sibling guard that this template lacks)What
The CloudFormation template accepts the all-zeros placeholder thumbprint for any issuer URL. Its only validation is an
AllowedPatternrequiring 40 hexadecimal characters, which the all-zeros string satisfies.The Terraform sibling treats this as unacceptable and rejects the placeholder unless the issuer is one AWS validates natively (
login.microsoftonline.comoraccounts.google.com), with the reasoning recorded in the validation message:Failure scenario
A customer points the CloudFormation template at a self-hosted or third-party OIDC issuer and leaves
OIDCThumbprintat its default. AWS then performs no CA-chain validation on the issuer's TLS certificate. An attacker who can MITM or DNS-hijack the issuer's JWKS endpoint mints tokens thatsts:AssumeRoleWithWebIdentityaccepts, landing in a role that holdsec2:PurchaseReservedInstancesOffering,savingsplans:CreateSavingsPlan, andrds:PurchaseReservedDBInstancesOffering(template.yaml:96-149). The result is irreversible multi-year spend commitments in the customer's account.The customer has no signal that anything is wrong: the stack deploys cleanly, onboarding reports success, and the difference between this and the Terraform path is invisible unless they read both.
Fix direction
Port the Terraform guard into the template. Either:
Conditionthat fails the deployment whenOIDCThumbprintequals the all-zeros value andOIDCIssuerURLis not one of the AWS-natively-validated issuers (aFn::Ifselecting a deliberately-invalid resource, or anAWS::CloudFormation::Init-style assertion), orWhichever is chosen, the all-zeros default should be removed so a customer must make an explicit choice.
Related
sec(iac): onboarding paths drift) lists this as instance 4 of the cross-cutting pattern. That issue tracks the missing parity mechanism (CI parity tests across onboarding paths); this issue tracks the individual fix to this template, which is needed regardless of whether the parity mechanism lands.OIDCSubjectClaimdefaulting to empty so the trust policy has no:subcondition. Both defects are in the same trust policy and should be fixed in one pass, but they are independent (fixing one leaves the other exploitable).