aws-s3-modify-code-artifact

s3:PutObject on a bucket that is a verified code-artifact deployment source (Lambda, CodePipeline, CloudFormation) for a compute workload equals modifying that workload's code.

derived aws emits CanModifyCode

match

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

{'principal': None} CanWriteData {'bucket': None} {'bucket': None} ContainsResourceReference {'compute': None}

where

node_type(?bucket) == ObjectStorage node_class(?compute) in [Compute, AnalyticsService] OR node_type(?compute) in [ServerlessFunction, BuildWorker, BatchJob, ApplicationPlatform] the ContainsResourceReference edge is typed as 'CodeSourceFor' or 'DeploymentSourceFor' (explicit evidence from config)

emit

source typeIdentity
target type*
source?principal
target?compute
permissionss3:PutObject
conditionsiam_permission resource_policy
state logicACTIVE when the CanWriteData(principal, bucket) edge is ACTIVE AND the ?bucket -> ?compute ContainsResourceReference edge is confirmed (code-source detected from Lambda GetFunctionConfiguration, CodePipeline config, or CloudFormation template). Inherits weakest state from the contributing CanWriteData edge. BLOCKED when CanWriteData is BLOCKED.

Narrative

{principal.name} can write to {bucket.name} (s3:PutObject), which is the verified code-artifact deployment source for {compute.name} - overwriting the artifact injects attacker code that runs as {compute.name}'s execution identity.

Raw rule rules/derived/aws/s3.yaml

id: aws-s3-modify-code-artifact
emits: CanModifyCode
description: s3:PutObject on a bucket that is a verified code-artifact deployment source (Lambda, CodePipeline,
  CloudFormation) for a compute workload equals modifying that workload's code.
match:
- - principal: null
  - CanWriteData
  - bucket: null
- - bucket: null
  - ContainsResourceReference
  - compute: null
where:
- node_type(?bucket) == ObjectStorage
- node_class(?compute) in [Compute, AnalyticsService]  OR  node_type(?compute) in [ServerlessFunction,
  BuildWorker, BatchJob, ApplicationPlatform]
- the ContainsResourceReference edge is typed as 'CodeSourceFor' or 'DeploymentSourceFor' (explicit evidence
  from config)
emit:
  source_type: Identity
  target_type: '*'
  source: ?principal
  target: ?compute
  permissions:
  - s3:PutObject
  conditions:
  - iam_permission
  - resource_policy
  state_logic: ACTIVE when the CanWriteData(principal, bucket) edge is ACTIVE AND the ?bucket -> ?compute
    ContainsResourceReference edge is confirmed (code-source detected from Lambda GetFunctionConfiguration,
    CodePipeline config, or CloudFormation template). Inherits weakest state from the contributing CanWriteData
    edge. BLOCKED when CanWriteData is BLOCKED.
  confidence: min(contributing_confidences) * 0.85
  derived_from:
  - ?principal CanWriteData ?bucket (s3:PutObject)
  - ?bucket ContainsResourceReference ?compute (code-artifact source via explicit normalization)
  - "can-execute-as:execute-as-via-code-modify (roll-up \u2014 cited not re-derived)"
  false_positive_note: "This rule ONLY matches when ContainsResourceReference is present with code-source\
    \ evidence. S3 event notifications (CanTrigger) are NOT sufficient \u2014 they indicate that a Lambda\
    \ subscribes to bucket events but do NOT prove the bucket is the deployment source for the Lambda's\
    \ code. Lambda event-triggered execution and Lambda code deployment are distinct patterns; do not\
    \ conflate them. Versioned buckets: if the compute uses a pinned s3ObjectVersion, a new PutObject\
    \ creates an unreferenced version (not injected); in that case downgrade to CONDITIONAL(trigger_exists)."
  narrative: "{principal.name} can write to {bucket.name} (s3:PutObject), which is the verified code-artifact\
    \ deployment source for {compute.name} \u2014 overwriting the artifact injects attacker code that\
    \ runs as {compute.name}'s execution identity."
move · open · esc close