avatarTeri Radichel

Summary

The context discusses how to prevent the confused deputy attack in batch job roles in CloudFormation templates.

Abstract

The context discusses a method to prevent the confused deputy attack in batch job roles in CloudFormation templates. The author suggests limiting the role template to creating roles for IAM-related batch jobs that can only be assumed by the IAM administrator and batch job roles for data processing that can only be assumed by the Batch Job Administrator. This can be achieved by removing the ARN parameter, adding a batch job type parameter, and using conditions to set the role name and ARN based on the batch job type. The author also provides code examples and explanations to illustrate the changes needed in the CloudFormation template.

Opinions

  • The author believes that limiting the role template can prevent the confused deputy attack in batch job roles.
  • The author suggests using conditions to set the role name and ARN based on the batch job type.
  • The author provides code examples and explanations to illustrate the changes needed in the CloudFormation template.
  • The author recommends testing the changes to ensure that they do not break any existing code.
  • The author acknowledges that there may be errors that are hard to pinpoint and suggests running individual test scripts to identify and fix them.
  • The author notes that there may be a problem in one of the administrator role policies and promises to address it in the next post.

Conditions and Mappings in CloudFormation Templates

ACM.32 Preventing the Confused Deputy Attack in Batch Job Roles

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

⚙️ Check out my series on Automating Cybersecurity Metrics. The Code.

🔒 Related Stories: IAM | AWS Security | DevOps | Cloud Security Architecture

💻 Free Content on Jobs in Cybersecurity | ✉️ Sign up for the Email List

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I wrote about the Confused Deputy Attack in the last post and how it could affect the Batch Job Role we created with the option to pass in any ARN.

We can fix this problem by limiting our role template to creating roles for IAM-related batch jobs that can only be assumed by our IAM administrator and batch job roles for data processing that can only be assumed by our Batch Job Administrator.

Remove the ARN parameter.
Add a batch job type parameter.
The batch job type parameter can only have two values: batch or iam.
If the value passed in is batch, our role name will have a batch prefix and only batch job administrator will be allowed to assume the role.
If the value passed in is iam, our role name will start with an iam prefix and only the iam administrator will be allowed to assume the role.

Refactoring the code

Just a reminder, the code we are modifying is the generic batch job role we modified in this post to allow an IAM administrator to assume a batch job role as well as a Batch Job administrator.

Remove the ARN parameter

First we want to remove the arm parameter. That’s easy.

Add a new batch job parameter with allowed values

Next we want to add a batch job type parameter, but we only want to allow someone to pass in one of two values: iam or batch.

We can do that with the AllowedValues attribute of our parameter which allows us to specify the values that CloudFormation will accept for the parameter. From the documentation:

Format:

So we’ll create our new parameter like this:

Adding conditions to our CloudFormation template

Next we have want to set values conditionally based on the value passed into the batchjobtype parameter. We can use AWS Conditions for this purpose:

If you look at our existing template it has a Parameters and a Resources section.

To use conditions we are going to add a Conditions section.

We can use different types of conditions in a CloudFormation template and all of them except the If function go in the Conditions section of the template.

Setting values based on Batch Job Type with condition functions

We can use CloudFormation’s Equals condition to determine if the batch job value matches batch or iam:

Then we can use the If condition to set a value based on whether the parameter equals a certain value:

We’ll add the Equals condition in the Conditions section of the template. Then we’ll reference that condition in our If statements later.

Using conditions to set the role name

We’ll start with the role name. We’re going to change the current value for RoleName but we’ll continue to use the jobnameparam at the end of the rolename.

If we wanted to use conditions to set the role name we could create conditions like this:

Then we could later use an If statement to set the role name based on whether the Condition IAM job equals true or BatchJob equals true. Let’s thing about how that would work a bit more.

Later in our template when we want to set the role name we could use this:

We could write something like this where we’d calculate the proper ARNs like we did before:

!If [IAMJob, '*IAM administrator ARN*', '*Batch Administrator ARN*']

The first question is, do we want to assume that if it’s not the IAM admin then it’s the Batch job admin? Maybe we want to be more specific with something like this: (pseudo code I haven’t tested):

!If [IAMJob, '*IAM administrator ARN*', !If [BATCHJob, '*Batch administrator ARN*','ERROR']

But what if we want to add other types of batch jobs in the future with different ARNs that can assume the roles for those batch jobs? Now our code is starting to feel not so nice. Sometimes this is referred to as “code smell.”

There’s another construct in CloudFormation we can use to solve this problem.

CloudFormation Mappings

CloudFormation has the concept of mappings that let you map one value to another value that will be used in a template.

Mappings is also a separate section of the template like Parameters, Conditions, and Resources. The format in yaml looks like this:

We can create a mapping for our batch job roles with multiple values for each mapping. I’m just using placeholders for the values right now:

!FindInMap [BatchJobRoleMap, !Ref ${batchjobtype}, rolename]

We reference our mapping table, look up the mapping that matches our batch job type parameter value, and get the role name.

First, fix the role name in the mappings. Set the role name to the existing role name in the template but change the prefix on the IAM value.

Next, calculate the role ARN for each mapping. We’ll presume that the role should be created in the Account where the CloudFormation template gets executed for now.

Now we can use our mapping in the template to update the role name and arn in our role. We’ll add the FindInMap function to get the appropriate value:

We need to update the deploy.sh file for this role as well. We’ll should change the argument name used in the script and we have to change the parameter name. We also need to change the parameter validation and should return a user-friendly error message to let the caller know they need to pass in “iam” or “batch”. Note that I didn’t change the stack name just yet. That’s because if I change the name of the stack, the existing resources won’t get updated and we’ll end up with two stacks — one with the old name and one with the new name — and two roles.

Here are the updates. When I made these updates I realized I should go back to the CloudFormation template and change the parameter name to end in “param” for consistency.

Here’s where I get the following error:

An error occurred (ValidationError) when calling the CreateChangeSet operation: Template format error: Every Mappings attribute must be a String or a List.

Basically we can’t include parameters or pseudo parameters in our mappings. What can we do? Include only the part of the string that we need for a differentiated value. Then concatenate parameters with our FindInMap value.

The mapping section becomes:

We can concatenate our mapping value with the other portion of the string we are formulating for our role name and ARN using the CloudFormation Join function:

As an alternate to a list of strings in YAML we can use this format:

So the role values change as follows:

Test the template with the batch job name POC we used before and pass in the job type: batch.

./deploy.sh POC batch

Now we can go check to see if our POC role has the correct ARN. Yes it does.

Now let’s try to redeploy the POC job with the iam credentials.

Note that you will need to delete the existing POC batch job first due to the fact that you will otherwise end up with two stacks trying to export an output with the same name. I should probably fix that.

./deploy.sh POC iam

Now we can check for our POC role again. It’s been updated to have the prefix IAMRole.

Our batch job role now also has a trust policy that allows the IAM administrator to assume the role.

We’re going to have fix a few other things now though. The deployment files we created earlier are passing in an ARN instead of a job type. We need to update this file for the batch job we are working on that deploys the batch administrator credentials:

jobs/iam/DeployBatchJobCredentials/deploy.sh

Change references to the IAM administrator ARN to pass in the batch job type instead. In addition we aren’t actually using the rolename variable so that can be removed.

This nicely simplifies our template:

We also need to edit the test.sh file that passes in an ARN to test the POC batch job:

Now run the test script in the root folder to make sure our changes did not break any of our code:

./test.sh

All the tests run successfully but notice that a lot of the templates didn’t change. To double check everything deploys correctly I deleted the Batch job policy and role CloudFormation stacks for the POC job and the DeployBatchJobCredentials job. Then I re-ran the test. All the CloudFormation templates deployed successfully.

Note that it will take a while for the IAM policies to kick in. If you get an error saying the IAM administrator is not authorized, save that for the next post.

Matching our resource and stack name for the IAM role

The CloudFormation stack won’t update the existing resources if the stack name changes, it will create a new stack. We’re going to change the name of the stack to match the name of the resource we’re creating (my personal preference). But note that you will need to delete the stack with the old name because a new stack with a new name will be created.

You’ll need to delete policy first because it depends on the role. Delete the two stacks below in this order:

Now return to the deploy.sh script and change the stack name as follows:

The first line adds the batchjobtype variable value at the beginning of the name. The second line makes the first character uppercase.

There’s one other thing we’re going to need to change. Our kms test script references the name of the stack for the IAMDeployCredentials job to get the batch job role ARN. Update that to have the IAMJob instead of BatchJob prefix.

Run the test script in the root of the repo directory again.

If at any point you get the KMS is Not Allowed error, refer to this post:

In order to delete the CloudFormation stacks you have to delete the alias and key using the kms profile first. There’s a schedule-key-deletion script in the kms directory. The problem is that he key will hang around with the same name for 7 to 30 days. You can also make a slight modification to the CloudFormation script to get it to update if it’s not updating after deleting the role formerly in the key policy.

All the CloudFormation stacks should complete successfully except the last one. If you have any errors that are hard to pinpoint, run each individual test script in the iam, kms, and jobs folder separately. Fix each error and then run the overall test script.

You might get an error with the last script related to the IAM role. That’s expected for now:

We’ll fix this in the next post when we look at how to prevent the confused deputy problem in IAM Policies. We have a problem in one of our administrator role policies now. Do you remember which one?

Follow for updates.

Teri Radichel | © 2nd Sight Lab 2022

About Teri Radichel:
~~~~~~~~~~~~~~~~~~~~
⭐️ Author: Cybersecurity Books
⭐️ Presentations: Presentations by Teri Radichel
⭐️ Recognition: SANS Award, AWS Security Hero, IANS Faculty
⭐️ Certifications: SANS ~ GSE 240
⭐️ Education: BA Business, Master of Software Engineering, Master of Infosec
⭐️ Company: Penetration Tests, Assessments, Phone Consulting ~ 2nd Sight Lab
Need Help With Cybersecurity, Cloud, or Application Security?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
🔒 Request a penetration test or security assessment
🔒 Schedule a consulting call
🔒 Cybersecurity Speaker for Presentation
Follow for more stories like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
❤️ Sign Up my Medium Email List
❤️ Twitter: @teriradichel
❤️ LinkedIn: https://www.linkedin.com/in/teriradichel
❤️ Mastodon: @teriradichel@infosec.exchange
❤️ Facebook: 2nd Sight Lab
❤️ YouTube: @2ndsightlab
Confused Deputy
Iam Role
AWS
Arn
Sts
Recommended from ReadMedium