aws-rds-modify-instance-resets-password

rds:ModifyDBInstance or rds:ModifyDBCluster with MasterUserPassword resets the master DB password to an attacker-known value, granting superuser DB access without knowing the current password.

derived aws emits CanReadData

match

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

{'principal': None} CanModifyConfiguration {'db': None}

where

node_type(?db) == RelationalDatabase ?db.provider_type in ['AWS::RDS::DBInstance', 'AWS::RDS::DBCluster'] ?principal has EFFECTIVE rds:ModifyDBInstance (or rds:ModifyDBCluster for clusters) on ?db ARN no IAM condition restricts rds:ModifyDBInstance to deny MasterUserPassword parameter changes (no rds:DatabaseClass, rds:DatabaseEngine, or StringLike conditions that would specifically block password changes)

emit

source typeIdentity
target typeRelationalDatabase
source?principal
target?db
permissionsrds:ModifyDBInstance rds:ModifyDBCluster
conditionsiam_permission scp_or_org_policy service_state
state logicACTIVE when rds:ModifyDBInstance (or rds:ModifyDBCluster for Aurora clusters) is confirmed EFFECTIVE on the DB ARN — identity-based policy, no SCP denial, and no permission boundary block on the action. CONDITIONAL(service_state) when the DB is in a non-AVAILABLE state (stopping, starting, maintenance, or storage-optimization) — ModifyDBInstance is accepted but ApplyImmediately matters: if ApplyImmediately=false the password change is deferred to the next maintenance window (emit ACTIVE for the capability; note the deferral). BLOCKED when an SCP or permission boundary explicitly denies rds:ModifyDBInstance. Note: IAM conditions on rds:ModifyDBInstance typically restrict engine type or size, not the specific MasterUserPassword parameter; unless the policy explicitly denies the parameter change (uncommon), treat the reset as feasible.

Narrative

{principal.name} can reset the master DB password for {db.name} (rds:ModifyDBInstance / rds:ModifyDBCluster) without knowing the current password, then connect as the database superuser to read, modify, or dump all data. This is the highest-value single-permission RDS escalation primitive.

Raw rule rules/derived/aws/rds.yaml

id: aws-rds-modify-instance-resets-password
emits: CanReadData
description: rds:ModifyDBInstance or rds:ModifyDBCluster with MasterUserPassword resets the master DB
  password to an attacker-known value, granting superuser DB access without knowing the current password.
match:
- - principal: null
  - CanModifyConfiguration
  - db: null
where:
- node_type(?db) == RelationalDatabase
- ?db.provider_type in ['AWS::RDS::DBInstance', 'AWS::RDS::DBCluster']
- ?principal has EFFECTIVE rds:ModifyDBInstance (or rds:ModifyDBCluster for clusters) on ?db ARN
- no IAM condition restricts rds:ModifyDBInstance to deny MasterUserPassword parameter changes (no rds:DatabaseClass,
  rds:DatabaseEngine, or StringLike conditions that would specifically block password changes)
emit:
  source_type: Identity
  target_type: RelationalDatabase
  source: ?principal
  target: ?db
  permissions:
  - rds:ModifyDBInstance
  - rds:ModifyDBCluster
  conditions:
  - iam_permission
  - scp_or_org_policy
  - service_state
  state_logic: "ACTIVE when rds:ModifyDBInstance (or rds:ModifyDBCluster for Aurora clusters) is confirmed\
    \ EFFECTIVE on the DB ARN \u2014 identity-based policy, no SCP denial, and no permission boundary\
    \ block on the action. CONDITIONAL(service_state) when the DB is in a non-AVAILABLE state (stopping,\
    \ starting, maintenance, or storage-optimization) \u2014 ModifyDBInstance is accepted but ApplyImmediately\
    \ matters: if ApplyImmediately=false the password change is deferred to the next maintenance window\
    \ (emit ACTIVE for the capability; note the deferral). BLOCKED when an SCP or permission boundary\
    \ explicitly denies rds:ModifyDBInstance. Note: IAM conditions on rds:ModifyDBInstance typically restrict\
    \ engine type or size, not the specific MasterUserPassword parameter; unless the policy explicitly\
    \ denies the parameter change (uncommon), treat the reset as feasible."
  confidence: min(contributing_confidences) * 0.95
  derived_from:
  - ?principal CanModifyConfiguration ?db (rds:ModifyDBInstance / rds:ModifyDBCluster effective permission)
  false_positive_note: "This rule emits CanReadData because resetting the master password IS gaining data\
    \ access \u2014 after the reset the attacker connects as superuser. However, it is a DESTRUCTIVE mutation:\
    \ it disrupts the legitimate master user's access and is highly detectable in CloudTrail (ModifyDBInstance\
    \ or ModifyDBCluster call). ApplyImmediately=false defers the change to the maintenance window \u2014\
    \ for the CanReadData edge, emit ACTIVE (the capability exists) but note the deferral in the evidence.\
    \ Do NOT downgrade to CONDITIONAL for this common IAM pattern unless a specific IAM condition explicitly\
    \ blocks MasterUserPassword changes. Confirm the DB is AVAILABLE (not STOPPED, CREATING, or in MODIFYING\
    \ state for another operation). For RDS Custom (OS-accessible), the password reset path is the same\
    \ but the attacker also gains OS-level access (model separately)."
  narrative: '{principal.name} can reset the master DB password for {db.name} (rds:ModifyDBInstance /
    rds:ModifyDBCluster) without knowing the current password, then connect as the database superuser
    to read, modify, or dump all data. This is the highest-value single-permission RDS escalation primitive.'
move · open · esc close