Skip to content

sec(iac): setup-gcp-wif.sh provider-reuse path validates attribute condition but not attribute mapping #1672

Closed

Description

@cristim

Found by independent adversarial review of PR #1651 (merged as `3fc9b5700`), after that PR merged.

Where

`arm/CUDly-CrossSubscription/setup-gcp-wif.sh`, provider-reuse path. The existing-provider branch compares `attributeCondition` against the value this script would have written, but never compares `attributeMapping`. The condition is only meaningful relative to the mapping that produces the value it evaluates: validating one without the other checks half the property.

Bypass

A pre-existing provider whose condition is byte-identical to expected (so the existing check passes) but whose mapping is:

```
attribute.aws_role = 'arn:aws:sts::' + assertion.account + ':assumed-role/' + assertion.arn.extract('assumed-role/{role_name}/')
```

An attacker holding only `iam:CreateUser` in the trusted AWS account creates an IAM user with path `/assumed-role/CUDly-Execution/`. `extract('assumed-role/{role_name}/')` yields `CUDly-Execution`, so `attribute.aws_role` becomes exactly the pinned role ARN, satisfying both the condition and the narrow `principalSet` grant. Full service-account impersonation; the script reports success ("Reusing existing provider (attribute condition matches: ...)").

Same substring-vs-normalisation bypass class as #1667's Terraform bug, reachable here only through a hand-crafted mapping on a provider this script did not itself create (its own create path writes condition and mapping together and is not affected).

Precondition (why not p0)

Requires a pre-existing provider with a hand-written, malicious mapping already in place before a re-run of this script. Narrower than #1544/#1667 (which required no prior tampering), so filed p1/high rather than p0/critical. Still full impersonation once triggered, and the fix is small.

Fix

PR incoming: compare the existing provider's `attributeMapping` against the expected value on reuse, normalising for the fact that `gcloud`'s `value(...)` printer renders it as semicolon-joined sorted pairs rather than the comma-joined form `--attribute-mapping` takes as input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions