aws-cc-cross-account-push-code-inject
A cross-account GitPush grant in the repository resource policy lets an external principal inject code into pipelines in the repository-owning account.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?repo) ==
ArtifactRepository
?repo.provider_type == 'AWS::CodeCommit::Repository'
?ext_principal.account != ?repo.account # cross-account
effective permission includes codecommit:GitPush on ?repo ARN for ?ext_principal (from resource policy + caller IAM policy, dual-policy eval)
exists a BuildWorker ?runner in ?repo.account whose source is ?repo AND tracked branch intersects the push scope
emit
| source type | Identity |
|---|---|
| target type | BuildWorker |
| source | ?ext_principal |
| target | ?runner |
| permissions | codecommit:GitPush |
| conditions | iam_permission resource_policy |
| state logic | CONDITIONAL(iam_permission, resource_policy) by default: cross-account access requires BOTH the resource policy grant (in the repo-owning account) AND an IAM policy grant in the caller's own account. Confirm both sides before upgrading to ACTIVE. BLOCKED when either side is denied (SCP in the repo account denying cross-account push, or no matching IAM grant in the caller account). |
Narrative
{ext_principal.name} (account {ext_principal.account}) has codecommit:GitPush on {repo.name} via its resource policy; pushing to the branch {runner.name} tracks injects attacker code into {runner.name}'s build, running as {runner.name}'s service role in account {repo.account}.
Raw rule rules/derived/aws/codecommit.yaml
id: aws-cc-cross-account-push-code-inject
emits: CanModifyCode
description: A cross-account GitPush grant in the repository resource policy lets an external principal
inject code into pipelines in the repository-owning account.
match:
- - ext_principal: null
- HasPermission
- repo: null
where:
- node_type(?repo) == ArtifactRepository
- ?repo.provider_type == 'AWS::CodeCommit::Repository'
- '?ext_principal.account != ?repo.account # cross-account'
- effective permission includes codecommit:GitPush on ?repo ARN for ?ext_principal (from resource policy
+ caller IAM policy, dual-policy eval)
- exists a BuildWorker ?runner in ?repo.account whose source is ?repo AND tracked branch intersects the
push scope
emit:
source_type: Identity
target_type: BuildWorker
source: ?ext_principal
target: ?runner
permissions:
- codecommit:GitPush
conditions:
- iam_permission
- resource_policy
state_logic: 'CONDITIONAL(iam_permission, resource_policy) by default: cross-account access requires
BOTH the resource policy grant (in the repo-owning account) AND an IAM policy grant in the caller''s
own account. Confirm both sides before upgrading to ACTIVE. BLOCKED when either side is denied (SCP
in the repo account denying cross-account push, or no matching IAM grant in the caller account).'
confidence: 0.88
derived_from:
- codecommit:GitPush effective via resource policy (cross-account)
- ?runner source binding to ?repo branch
false_positive_note: "Cross-account CodeCommit access uses standard dual-policy evaluation: the resource\
\ policy in the repository-owning account + an IAM policy in the calling principal's account must\
\ both allow the action. Confirm the IAM side before emitting ACTIVE. Honor codecommit:References\
\ conditions on either policy side. This rule emits CanModifyCode (not CrossAccountTrust) because\
\ it is the CanModifyCode FACT \u2014 the CrossAccountTrust explicit edge is separately emitted by\
\ the explicit normalization rules (aws-codecommit.yaml, rule cross-account-policy). cicd-chains then\
\ collapses the resulting CanModifyCode + ExecutesAs into CanExecuteAs, and can-control produces CanEnterAccount\
\ for the owning account."
narrative: '{ext_principal.name} (account {ext_principal.account}) has codecommit:GitPush on {repo.name}
via its resource policy; pushing to the branch {runner.name} tracks injects attacker code into {runner.name}''s
build, running as {runner.name}''s service role in account {repo.account}.'