Google Cloud Platform (GCP) Storage Access Analysis

By
  1. Principals: Users, Groups, Domains or the Public as a whole
  2. IAM Roles: Permissions for cloud actions
  3. Resources: Any cloud resource with a resource identifier

This structure mirrors how JupiterOne models Microsoft Azure role-based access control (RBAC), as described in our previous article, Azure Access Review using Optional Traversals in JupiterOne. The following scenario demonstrates how to generate the primary J1QL query to secure a Google Cloud Storage bucket.

Scenario: Query IAM Role Bindings

You have the answer to life, the universe, and everything...

42


… and you want to keep it safe in a super-secret storage bucket in Google Cloud. In order to make sure no one else can manipulate it, you decide to do an access analysis of your storage bucket. The first thing to check is to see if there are any nefarious individuals that have admin access to your bucket.

Using JupiterOne Query Language (J1QL), you can query for the IAM Role Bindings that are attached to this bucket which allow the permission  storage.admin .

 /* Resource */   
Find google_storage_bucket with name=
'j1-gc-integration-dev-v3-super-secret-stuff'
/* Binding */
that ALLOWS AccessPolicy with permissions='storage.admin'
/* Principal */
that ASSIGNED (User|Domain|UserGroup)return TREE

Google Cloud Storage - JupiterOne - 01

Well, that’s not good!  Not only does this shady mknoedel individual have admin access to your super-secret storage bucket, so does everyone else! These bindings need to be removed.

Google Cloud Storage - JupiterOne - 02

Job well done! Your secret is now safe… or is it? Google Cloud uses a Resource Hierarchy, which allows users to attach role bindings at different organizational levels, with each level being a potential vector for granting access to your bucket.

Google Cloud Storage - JupiterOne - 03

You’ll need to check those bindings as well, just to be safe. Using J1QL, you can query for the IAM Role Bindings that are attached anywhere on the organization hierarchy which allow the permission storage.admin .

/* Resource */ 
Find google_storage_bucket with name='
j1-gc-integration-dev-v3-super-secret-stuff'
that HAS google_cloud_api_service  
/* Recursively check for project, folder, and org bindings */
(that HAS google_cloud_project)?  
/* folders can be nested so be sure to query multiple levels */
(that HAS google_cloud_folder)?
(that HAS google_cloud_folder)?
(that HAS google_cloud_folder)?
(that HAS google_cloud_organization)? as policyLevel
  /* Binding */
that ALLOWS AccessPolicywith permissions='storage.admin'
/* Principal */
that ASSIGNED (User|Domain|UserGroup)return TREE

Don’t know what the `(...)?` syntax means? Check it out here!

organization-traversal

Good thing we checked! This unknown user mknoedel is granted admin access to our bucket at all levels of the organization hierarchy. Let’s remove these bindings.

Cloud Storage supports “Convenience Members”, which are a special set of principles that can be applied specifically to IAM bucket policies. A convenience member acts as a bridge between the principals granted a basic role and an IAM Role. The IAM Role granted to the convenience value is, in effect, also granted to all principals of the specified basic role for the specified project ID.

Using J1QL, we can find all the bindings that have Convenience Members that escalate the permissions of basic roles to  storage.admin  for our bucket.

/* Resource */ 
Find google_storage_bucket with name=
'j1-gc-integration-dev-v3-super-secret-stuff'
/* Binding */
that ALLOWS AccessPolicy with permissions='storage.admin'  
/* expand "Convenience" members */  
(that ASSIGNED >> AccessRole)?
(that USES << AccessPolicy)?
  /* Principal */  
that ASSIGNED (User|Domain|UserGroup)return TREE
Google Cloud Storage - JupiterOne - 05

Gotcha! Anyone who has a Google account with a domain of “mknoedel.com” has admin access to our super-secret bucket. You’ll need to remove this binding as well.

Pulling it All Together: Access Analysis with J1QL

You can do the entire access analysis with the J1QL query: Who has  storage.admin  on the  j1-gc-integration-dev-v3-super-secret-stuff  key vault?

full-access-graph-with-markup (1)

Takeaways

With J1QL you gain a deep insight into who has access to your Google Storage buckets. Going even further, you can use the sort of analysis examined above to easily evaluate how your infrastructure lines up with Google Cloud’s IAM Best Practices:

  • Use the principle of least privilege when granting access.

    Am I using the
    principle of least privilege when granting access to my buckets?

    Use the above query to search for storage.admin over all buckets. When found, reduce the scope to something less aggressive like storage.objectReader.

  • Avoid granting roles with setIamPolicy permission to people you do not know.

    Does anyone with an email not in the domain jupiterone.com have setIamPolicy permission to my buckets?
 /* Resource */
Find google_storage_bucket
(that HAS google_cloud_api_service)?
/* Recursively check for project, folder, and org bindings */
(that HAS google_cloud_project)?
/* folders can be nested so be sure to query multiple levels */
(that HAS google_cloud_folder)?
(that HAS google_cloud_folder)?
(that HAS google_cloud_folder)?
(that HAS google_cloud_organization)? as policyLevel
/* Binding */
that ALLOWS AccessPolicy with permissions='storage.setIamPolicy'
/* expand "Convenience" members */
(that ASSIGNED >> AccessRole)?
(that USES << AccessPolicy)?
/* Principal */
that ASSIGNED (User|Domain|UserGroup)
/* Optionally unwind Groups and Domains to Users */
(that HAS User)? as principal
where principal.email!='jupiterone.com' AND
principal.domainName!='jupiterone.com'return TREE


  • Be careful how you grant permissions to anonymous users.

    Have I assigned any of my storage buckets to Everyone?
 /* Resource */  
Find google_storage_bucket (that HAS google_cloud_api_service)?  
/* Recursively check for project, folder, and org bindings */
(that HAS google_cloud_project)?  
/* folders can be nested so be sure to query multiple levels */  
(that HAS google_cloud_folder)?  
(that HAS google_cloud_folder)?
(that HAS google_cloud_folder)?
(that HAS google_cloud_organization)? as policyLevel  
/* Binding */
that ALLOWS AccessPolicy  
/* expand "Convenience" members */  
(that ASSIGNED >> AccessRole)?  
(that USES << AccessPolicy)?
  /* Principal */
that ASSIGNED Everyonereturn TREE


Resources

Michael Knoedel
Michael Knoedel

Michael is a full stack developer who has a passion and a talent for design. He's engaged in a career in computer science that not only allows him to solve highly-challenging technical problems which he has proven to excel at, but also allows him to use his extensive design skills to facilitate excellent user experiences. He is a disciplined and talented developer who can do it all.

To hear more from Michael, get our newsletter. No spam, just the good stuff once or twice a month. Sign up below.

Keep Reading

Identify compromised versions of Github using JupiterOne
January 31, 2023
Blog
Identify compromised versions of GitHub apps using JupiterOne

As a preventative measure, Github will be deprecating the Mac and Windows signing certificates used to sign Desktop app versions 3.0.2-3.1.2 and Atom versions 1.63.0-

The top 11 questions that every CISO should be able to answer
January 30, 2023
Blog
The top 11 questions that every CISO should be able to answer

In part one of this two-part series, we polled some of our top security experts to see what it takes to succeed secure and manage resources effectively.

Best of Cyber Therapy, Season 1
January 25, 2023
Blog
Best of Cyber Therapy, Season 1

Take a look at the top 5 episodes from Season 1 of Cyber Therapy, a video podcast featuring the humans of cybersecurity!

15 Mar 2022
Blog
One line headline, one line headline

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud eiut.

15 Mar 2022
Blog
One line headline, one line headline

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud eiut.

15 Mar 2022
Blog
One line headline, one line headline

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud eiut.