It’s a new beginning! Ermetic is now Tenable Cloud Security.

Not Just Buckets: Are You Aware of ALL Your Public Resources?

A misconfiguration of resource based policies can inadvertently make resources public. Do you have such misconfigured policies present in your environment?

Lior Zatlavi By Lior Zatlavi
Not Just Buckets: Are You Aware of ALL Your Public Resources?

Public exposure of resources is a point of dread for many security practitioners. Public resources are low hanging fruit for attackers seeking to access sensitive information or manipulate an activity -- or even deny the availability of mission-critical resources.

One well-known culprit for exposing resources is AWS built-in mechanisms. While misconfiguring them is a common, and legitimate, concern for security practitioners charged with protecting AWS environments, we often see another mechanism in use that may be even more misconfiguration-prone: resource based policies.

We’ll touch briefly on built-in mechanisms but focus this post primarily on this lesser known cause: the configuration intricacies of resource policies that can render resources as exposed and out in the open as a deer caught in headlights.

Proceed with caution: Built-in mechanisms

AWS offers built-in mechanisms for configuring certain resource types as public. One notable such mechanism is Access Control Lists (ACLs) for S3 (Simple Storage Service) buckets -- a widely used and highly durable AWS storage service. The ACL mechanism can make certain actions publicly accessible so they can be performed on a bucket.

All that is needed to grant public access when using ACLs is to allow permissions to the “Everyone” group. You can publicly allow the listing, the writing or overwriting of a bucket’s contents, and even the changing of the ACL itself.

Allowing permissions to the Everyone group is obviously a practice to be discouraged. AWS warns users clearly when they attempt such a configuration. Also to AWS’s credit, we can report that the abilities to configure writing as a public permission in an ACL or overwriting the ACL are not available via the console, only by using the cli. This limitation minimizes the chance that such sweeping permissions will be granted by mistake. AWS also offers effective mechanisms to outright deny ACLs from being applied at the bucket and account levels.

Other AWS built-in mechanisms are also available, including RDS snapshot sharing and AMI EC2 image sharing, for configuring resource types other than buckets as public. Let’s look now at resource based policies, which may be just as risky as built-in mechanisms in exposing resources.

Resource-based policies gone wildcard

A resource-based policy is a mechanism available on several types of AWS resources (see the services that support it here) that allows granting access directly on the resource. In contrast to an IAM policy, which can only grant permissions to the principals managed in the account, a resource-based policy allows granting access to principals outside the account. One just specifies the principal used to grant the permissions and... surprise, surprise: this can wind up being any AWS principal, from any AWS account. Let’s see how.

A statement from a resource-based policy may look like this:

      "Sid": "AllowAccessToExternalAccount",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<ACCOUNT_ID>:root"
      "Action": [
      "Resource": "<RESOURCE_ARN>"

In this case, the “Principal” field is clearly specified with a configuration that allows another account, via IAM policies, to grant access to the principals in it. Basic stuff, right? Yet, if misconfigured, a resource based policy can grant access to any principal.

In multiple real-world scenarios (including production environments), we’ve found resource based policies with statements using the following definition for the “Principal” field:

"Principal": {
     "AWS": "*"

This wildcard configuration is convenient to use when a developer or DevOps engineer doesn’t know exactly which principal will need access to the resource. They may instinctively think the open-ended designation gives access to only principals in the account the resource is at -- but this is not the case. The wildcard “*” means the statement applies to all principals the policy may apply to -- and a resource based policy could apply to any AWS principal in any AWS account. So the actual effect of this statement is to make the resource public for any actions the statement allows that aren’t denied elsewhere.

As Inigo Montoya might put it:

Inigo Montoya

Matters are even worse when the “Action” field also uses a wildcard, allowing all principals to perform all possible actions on the resource. It should also be noted that, in this case, the only way to actually deny access to perform the actions granted by the statement is with another statement on the resource based policy with a condition denying the access. A Service Control Policy (SCP), for example, won’t be any help since SCPs apply only to principals in the account to which they are attached. By definition, an SCP doesn’t affect principals from external accounts.

Faulty powers: Misconfigured resource policies

We detail below AWS resource types on which we found such an open-ended or otherwise faulty role or policy configuration, and its potential impact in making the resource public. Please remember that these instances are not theoretical, rather, were detected in real-world environments configured by savvy infrastructure teams from well respected organizations.

IAM Roles Exposed for Assuming

IAM Roles are a particularly interesting resource type that we found configured for public exposure. An IAM Role is in fact an AWS resource, and its “trust relationship” is actually a resource based policy. Allowing sts:AssumeRole to “AWS”: {“*”} would make the role potentially assumable by any principal.

This use case is interesting because an external principal allowed to assume an IAM Role would be able to use all the permissions in every policy attached to the role. Such a misconfiguration has huge potential fallout: it could well allow all external principals in an environment to have incredibly powerful permissions (all the way up to admin level).

Havoc on image permissions in ECR Repositories

AWS’s Elastic Container Registry (ECR) is a service that lets you “store, share and deploy your container software anywhere.” You create repositories to easily store and manage container images that you or anyone you share them with will pull later to deploy applications on containers -- using, for example, a Task Definition on AWS’s Elastic Container Service. ECRs offer other nice features such as scanning the stored container images for vulnerabilities -- and their API lets you streamline management of images and version lifecycles as part of your deployment process.

ECR repositories are also an AWS resource. As you may have guessed, they support resource based policies where we’ve seen misconfigurations. Let’s illustrate the problem: The following set of permissions is required to allow an identity to push an image to an ECR repository (as described here):

"Action": [

An identity granted these permissions may be able to push a new image to a repository with a certain tag; doing so effectively replaces a version currently used in an ECS task definition or that can be pulled for deployment using another tool. This configuration has potentially serious impact as it could allow a malicious actor to run its own software using the permissions the victim has provided to the service deploying it.

Note that if you’ve set an immutable tag on a repository, it won’t be possible to push an image under an existing tag. However, a malicious actor with access to ecr:PutImageTagMutability could change this configuration, as well.

A malicious actor can also use ecr:DeleteRepository or ecr:BatchDeleteImages to remove the repository and interrupt services that use it. Finally, if the containers include sensitive information or logic you don’t necessarily want to be public, even a permission such as ecr:BatchGetImage (along with ecr:GetAuthorizationToken for authentication), which allows pulling an image, could be quite sensitive.

Service denied and decryption through KMS keys

In AWS, one manages access to customer-managed KMS keys using IAM policies and key policies (KMS’s resource based policy), which could also make actions on the key publicly available.

In our recent study on permissions combinations that could be used to execute a ransomware attack on misconfigured S3 buckets, we discussed use of the kms:PutKeyPolicy permission to change the key policy set on a customer-managed KMS key. With this simple action alone, a malicious actor can hijack and deny access to the key. In doing so, it can deny the ability to use kms:Decrypt on the key -- effectively performing a Denial of Service attack on all the data encrypted using the key. This denial will not work in a cross account scenario but even allowing the permission to all principals within the account where the key is managed is pretty reckless.

Another interesting permission is kms:CreateGrant, which could be used cross account and provide any principal with permission to cryptographic actions, including kms:Decrypt on the key. As the AWS documentation says: “The grantee principal can be an identity in a different AWS account.”

In other words, if this permission is made public on a key, pretty much anyone can use it for decryption.

Letting others in on your Secrets Manager secrets

It’s no secret that AWS’s Secret Manager is great for securely holding sensitive strings that may be accessed by applications running on serverless resources and other compute functions. We’ve reviewed Secret Manager in our post on protecting access to secrets and also in a more recent post on storing secrets in tempting but unsuitable locations.

A Secrets Manager secret is an AWS resource that also supports a resource based policy. The resource can be made public in the method described above -- and by providing external identities with access to permissions such as secretsmanager:GetSecretValue, which is the sensitive information stored in the secret. The sensitive information can be a database connection string, an API key, an access token, etc. The ease of unwittingly exposing a secret through this permission is a good example of why using encryption with a customer-managed KMS key on a secret is a sound idea: even if the secret is made public, access to it wouldn’t be granted without the additional access to use kms:Decrypt on the key used to encrypt it.

Disrupting and accessing SQS Queues

AWS’s Simple Queue Service (SQS) is a fully managed MQ that you can, according to AWS, use to “send, store, and receive messages between software components.” It’s a great way to free developers from managing and operating such middleware at the expense of writing software. However, if access to certain permissions on a queue is compromised, the queue may be exposed to certain risks. For example, a malicious actor may be able to access sensitive data transferred on it by using sqs:ReceiveMessage, manipulate the queue’s activity by sending their own messages using sqs:SendMessage, interrupt its activity and cause malfunctions to your operation by deleting the queue altogether using sqs:DeleteQueue (note that this permission cannot be used cross account) or purge the queue’s current contents using sqs:PurgeQueue.

Mucking up communication on SNS topics

AWS’s Simple Notification Service (SNS) is a tool that enables application-to-application or application-to-person communication on a publisher/subscriber model. The user creates topics (an AWS resource) and a subscription for each topic, including a description of a protocol and an endpoint, such as an email address, to which messages will arrive once published on the topic.

A malicious actor that gains access to sns:Subscribe can also access the information shared on the topic. By gaining access to sns:Publish, the malicious actor can broadcast information to subscribers of the topic and by using permissions such as sns:DeleteTopic or even sns:Unsubscribe may disrupt the service activity. Even by using other read permissions of the pattern sns:List* or sns:Get*, a malicious actor can gather sensitive information about business activity supported by SNS.

Yet another public attack angle on S3 buckets

Finally, a bucket can also be made public in the same way as mentioned in the use cases above: by misconfiguring resource policies to (inadvertently) expose pretty much any permission imaginable to any external identity that may encounter it. Ill-defined resource policies can open a bucket to the public by allowing the listing and reading of its contents, its overwriting and deletion of the information on it. Remember: just because it’s not configured via an ACL doesn’t mean the bucket cannot be made public!


Understanding what resources in your cloud environment are publicly exposed is extremely important to being able to mitigate unintended access to them. Incorporating visibility into all public resources in your environment is an important feature for a cloud security product.

Figure - Visualization of public resources as shown in the Ermetic dashboard
Figure 1: Figure - Visualization of public resources as shown in the Tenable Cloud Security dashboard

Public access to a resource can be configured using a built-in mechanism however, where supported, resource-based policies are yet another critical mechanism that should be tracked to protect a cloud environment. Doing so enables you to detect and prevent unintended access to resources, especially by external identities to an account.

Effective tracking of resource based policies and the access they grant can be extremely hard when done manually. Automated, ongoing review of such configurations in your AWS environment is strongly recommended as a preferred approach.

Skip to content