- 
                Notifications
    
You must be signed in to change notification settings  - Fork 148
 
Description
I am not sure if this was a conscious design decision or not. Dependent actions are always added with wildcards (*) and may not be the expected behavior.
Example
When generating a policy document for write actions on a KMS key ARN, the dependent actions are added as wildcards which could lead to granting more permissions than anticipated.
kms:ReplicateKey is a write action that is added when I specify a key ARN (as designed)
Two dependent actions of it are kms:CreateKey and kms:PutKeyPolicy
I understand kms:CreateKey has no resource requirements and is added as a wildcard. kms:PutKeyPolicy on the other hand CAN take a key ARN as a resource constraint but is indiscriminately added as a wildcard action as well. This leads to the generated policy being able to put a key policy on any KMS key (if a key has the default key policy or an overly permissive one)
Observed behavior
- Sid: MultMultNone
  Effect: Allow
  Action:
  - kms:CreateKey
  - kms:PutKeyPolicy <--
  - kms:TagResource
  Resource:
  - '*' <--
Expected behavior
- Sid: KmsWriteKey
  Effect: Allow
  Action:
  ...
  - kms:Verify
  - kms:PutKeyPolicy <--
  - kms:TagResource
  Resource:
  - arn:aws:kms:us-east-1:123456789012:key/shaq <--
- Sid: MultMultNone
  Effect: Allow
  Action:
  - kms:CreateKey
  Resource:
  - '*'
Possible remediation
I attempted to add a bit of code to writing/sid_group.py to add the dependent action to the same SID as the other actions if they share the same resource constraint (but part of a different access_level).
if len(dependent_actions) > 0:
  for dep_action in dependent_actions:
      # If a dependent action has the same resource constraint, add it to actions 
      # instead of * which could grant more access than anticipated.
      for level in ["Read", "Write", "List", "Tagging", "Permissions management"]:
          if dep_action in get_actions_with_arn_type_and_access_level(
              service_prefix, resource_type_name, level):
                if not dep_action in actions:
                  actions.append(dep_action)
      if not dep_action in actions:
          self.add_action_without_resource_constraint(dep_action)