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.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
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 — 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.'