aws-cb-can-modify-code-source-write

Writing to the project's source repository/bucket on the tracked branch injects code into future builds when the buildspec is stored in-source.

derived aws emits CanModifyCode

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} CanWrite {'source': None}

where

?source is the source repository or bucket (CodeCommit repo / S3 bucket / GitHub/Bitbucket/GitLab repo) tracked by project ?project project.source.buildspec is empty OR project.source.buildspec == 'buildspec.yml' (stored in source) — NOT an inline or override buildspec ?source is the branch/ref the project's webhook or primary source monitors

optional

Present → upgrade the emitted state; absent → downgrade (not a hard requirement).

{'webhook': None} CanTrigger {'project': None}

emit

source typeIdentity
target typeBuildWorker
source?principal
target<CodeBuild Project (BuildWorker) that tracks ?source>
conditionsservice_state trigger_exists
state logicACTIVE when the principal can write to the tracked branch AND an existing webhook fires on push (matched(optional[0]) or webhook_exists(?project)); CONDITIONAL(trigger_exists) when the push would not automatically trigger a build (manual build only, no webhook); CONDITIONAL(branch_protection) when branch-protection or required-review gates the write (in which case the upstream CanWrite is already CONDITIONAL and this edge inherits it).

Narrative

{principal.name} can write to {source.name} (the source tracked by {project.name}); since the project reads its buildspec from source, a push to the monitored branch injects attacker-controlled commands into the next build, which runs as {role.name}.

Raw rule rules/derived/aws/codebuild.yaml

id: aws-cb-can-modify-code-source-write
emits: CanModifyCode
description: Writing to the project's source repository/bucket on the tracked branch injects code into
  future builds when the buildspec is stored in-source.
match:
- - principal: null
  - CanWrite
  - source: null
where:
- ?source is the source repository or bucket (CodeCommit repo / S3 bucket / GitHub/Bitbucket/GitLab repo)
  tracked by project ?project
- "project.source.buildspec is empty OR project.source.buildspec == 'buildspec.yml' (stored in source)\
  \ \u2014 NOT an inline or override buildspec"
- ?source is the branch/ref the project's webhook or primary source monitors
optional:
- - webhook: null
  - CanTrigger
  - project: null
emit:
  source_type: Identity
  target_type: BuildWorker
  source: ?principal
  target: <CodeBuild Project (BuildWorker) that tracks ?source>
  permissions: []
  conditions:
  - service_state
  - trigger_exists
  state_logic: ACTIVE when the principal can write to the tracked branch AND an existing webhook fires
    on push (matched(optional[0]) or webhook_exists(?project)); CONDITIONAL(trigger_exists) when the push
    would not automatically trigger a build (manual build only, no webhook); CONDITIONAL(branch_protection)
    when branch-protection or required-review gates the write (in which case the upstream CanWrite is
    already CONDITIONAL and this edge inherits it).
  derived_from:
  - ?principal CanWrite ?source
  - project.source binding (BatchGetProjects)
  - webhook config
  false_positive_note: "ONLY emit when the project reads its buildspec FROM source (default behavior when\
    \ no inline buildspec is set). If the project has an explicit inline buildspec (source.buildspec contains\
    \ YAML content, not a filename) or a buildspecOverride is always supplied at start time, the source\
    \ write does NOT control the buildspec \u2014 downgrade to POTENTIAL or do not emit. Branch protection\
    \ (required reviews, status checks) on the tracked branch makes the contributing CanWrite CONDITIONAL;\
    \ inherit that state. This edge models the supply-chain path: repo write + webhook = codeless RCE\
    \ as the service role."
  narrative: '{principal.name} can write to {source.name} (the source tracked by {project.name}); since
    the project reads its buildspec from source, a push to the monitored branch injects attacker-controlled
    commands into the next build, which runs as {role.name}.'
move · open · esc close