21 Feb, 2022
The following are factors that potentially increase this risk:
Rapid adoption of a cloud provider’s services
I.T. staff skills gap
Expedient migration of application workloads into production cloud environments
This combination of factors can result in problems like: broken authentication, compromised credentials, credentials stored in source code, account hacking, data breaches and more.
As larger numbers of users access these insecure cloud environments, the probability of a security breach increases. Anybody who knows a password or hacks into an account will be able to access confidential information, including customer personal identity information.
In this circumstance, it would be wise for an organisation to use multiple levels of authentication, and ensure that the passwords remain protected. Passwords should be modified regularly, especially when employees resign and leave the organisation. Access rights to usernames and passwords should be given judiciously. Often in the rush to migrate applications to the cloud, corners are cut and the Principle of Least Privilege is overlooked.
Principle of Least Privilege (PoLP)
The Principle of Least Privilege requires that any given computing component or person must be able to access only the information and resources that are necessary for it to fulfil its purpose.
Unfortunately, refining the granularity of the required permissions for a given process can be error prone, and therefore time consuming. That is why, for expediency’s sake, processes can end up being granted a lot more permissions than they actually need.
So with that in mind, let’s look at one way of remedying this situation.
An Example Scenario
In this example scenario we will focus on achieving these two objectives:
Removing plain text credentials from the application
Restricting the permissions granted to the application
For the purposes of this article, let’s imagine that our web application is called “Spork” and already exists in AWS. In order for it to access the AWS resources it needs to get the job done, an employee’s IAM user credentials have been referenced with the Spork application assuming that user. This IAM user’s Access Key ID and Secret Access Key have been stored in a configuration file, which is just one of many files that make up Spork’s source code. The IAM user, whilst not specifically granting administrator access, is granting far more permissions to Spork than it actually needs. Also the employee has since left the company.
To better secure the Spork application we need to do the following two things:
Remove the IAM user’s Access Key ID and Secret Access Key from the source code- we’ll achieve this by using an IAM role instead
Refine the permissions granted to that IAM role so that Spork has only the permissions it needs to function correctly, and no more
Removing plaintext credentials
We are going to remove the plaintext credentials from the source by transitioning from a user to a role. Before creating a new role we need to understand what permissions are currently being granted to the application. While we eventually want to restrict these, if we do so upfront we risk breaking the application by removing permissions it needs.
If we look at the current level of access granted to the IAM user using the AWS console, we can see that the following AWS managed policies are being used:
Figure 1
Create an IAM role
We can use the information above as a template to very quickly define an equivalent IAM role using CloudFormation as seen in Figure 2.
NOTE:
It’s always a good idea to use Infrastructure as Code techniques over “ClickOps”, but that is beyond the scope of our discussion here. People and tools - A love story by Kristy McDonald is a good article that will provide more insights into IaC.
Figure 2
Use the newly created IAM role
Once this CloudFormation template has been deployed, the IAM role can be used by the Spork application, rather than Spork having that IAM user’s access key ID and secret access key stored in its source code.
The “SporkApplicationRole” IAM role can be used by the Spork application by attaching an instance profile that specifies the role to the EC2 instance Spork runs on.
Now that the Spork application is using our new IAM role instead of the original IAM user we need to do some permissions investigation.
Figure 3: Comparing permission sets
As the venn diagram in figure 3 shows, the grand total of permissions granted to the original IAM user (and now to our IAM role) represents a massive superset of permissions needed for the Spork application to function correctly. This means that application code changes could have unintended consequences, regardless of whether those changes are made accidentally or with malice. This highlights the benefits of PoLP. But we need to find out exactly what permissions Spork is currently using so that we can grant it only those permissions it requires.
Refining the Role’s permissions
Using a combination of CloudTrail and Athena we can easily query the CloudTrail logs using SQL syntax. We will follow the below steps to refine the permissions needed for our “SporkApplicationRole”:
Create a database ‘cloudtrail’ in Athena
Create an external table ‘cloudtrail_logs’ in the database ‘cloudtrail’ in Athena
Query the ‘cloudtrail_logs’ table for IAM user activity
This will illustrate just how much access the Spork application has had previously
Query the ‘cloudtrail_logs’ table for “SporkApplicationRole” IAM role activity
After Spork has been using the role for one week we will see how little access it actually needs
Modify the application IAM role to have only the required permissions
Create the CloudTrail table in Athena
In the AWS console, we create an Athena table that allows us to query the CloudTrail logs using SQL syntax.
Figure 4
Retrieving the permission set of the User
Now we can query this table in a new Athena tab using the IAM user’s ARN in the WHERE clause:
Figure 5
As you can see, this retrieves many rows showing us how many permissions the IAM user “anotheremployee” has been granted:
Figure 6
Retrieving the permission set of the Role
Next, we can query the table in a new Athena tab using the newly created IAM role’s ARN in the WHERE clause:
Figure 7
As you can see, this query retrieves far fewer rows, showing us that even though the role has been granted just as many privileges, the Spork application is only using a couple of them:
Figure 8
Restricting the Role’s permissions
This means that our CloudFormation template can be modified (see below) to grant only the permissions needed by the Spork application.
Figure 9
Summary
In the introduction we considered these factors that can expose an organisation to increased security risks:
Rapid adoption of a cloud provider’s services
I.T. staff skills gap
Expedient migration of application workloads into production cloud environments
The Spork application was quickly migrated to AWS and the developers were unfamiliar with the concept of machine accounts and used an IAM user with a large permissions set instead - without the time to refine the access, they granted more than the application needed.
Hopefully this article has shown the power of Athena and CloudTrail to highlight the current permission set in use for IAM users and roles, and to make it an easy process to rein in those permissions without breaking an application’s functionality.