Signing URLs in GCP: Convenience vs. Security
Why `iam.serviceAccounts.signBlob` permission can cause trouble in your GCP environment
TL;DR
Intro
If you've ever worked with a cloud storage service (e.g., AWS S3, or GCP Cloud Storage) you may know that creating signed URLs is one way to provide secure, temporary access to objects stored on cloud buckets.
A signed URL contains authentication information, has an expiration time, and allows users without credentials to upload and download bucket objects. Anyone who knows the URL can access the resource until the URL expiration time is reached.
Signing URLs for GCP
GCP provides several ways to sign Cloud Storage URLs:
- Signing with HMAC authentication
- V2 signing with service account authentication
- V4 signing with service account authentication
Signing with HMAC authentication is used for compatibility with other cloud providers.
V2 signing is a legacy method for signing URLs with service account authentication.
This article will concentrate on two methods to create a V4 signature, which is the recommended way to sign URLs for Cloud Storage bucket objects. Notably, these methods also work for V2 signatures.
Signing via service account key
One way to generate a V4 signature is to sign a “blob” (arbitrary bytes) with a service account key (read more about service accounts here). The key is essentially a private RSA key that can be created for your service account (see docs). Cryptographically signing data with the service account private key allows GCP to both identify and authenticate data (in our case, signed URLs) and associate it with the corresponding service account.
Keep in mind, as stated in Google documentation, managing service account keys implies a security risk if the keys aren’t managed correctly, and the responsibility for securely managing these private keys falls directly to you. In addition, for serverless environments, such as App Engine, Cloud Functions, or Cloud Run, service account keys are an inconvenient way to sign URLs because it forces programmers to manage the key and deal with its secure storing and rotation.
This fact induces developers to seek other solutions that let them create signed URLs using service account attached to a computing instance.
Due to these factors, developers seek other easier solutions which let them create signed URLs using a service account attached to a computing instance. The instance uses the service account to interact with Google Cloud API using a temporary token that can be obtained via metadata endpoints, all without managing service account static credentials.
The documentation provides detailed information on implementing this method in your program. Alternatively, you can use Cloud Storage client libraries that already use this method.
These articles and sources explain why and how to use this method in detail:
- Go examples: “Uploading images directly to Cloud Storage using Signed URL” Google Cloud blog article
- Python: “How to Generate Signed URLs Using Python in Google Cloud Run” Medium article and “How to generate a Blob signed url in Google Cloud Run?” StackOverFlow answer
To exploit these conditions, a malicious user must only compromise a service account token (i.e., via SSRF, RCE, or local file read vulnerabilities) with the iam.serviceAccounts.signBlob permission. To make matters worse, the signBlob IAM method cannot be limited by IAM conditions, so there is currently no method for developers to limit what service accounts can be used to sign data.
Because of the way Google Cloud functions, the chance of finding a default service account with high privileges is almost 100%. Default service accounts are created automatically when you enable or use Google Cloud services, and let the service access other Google Cloud resources.
When a default service account is created, it is automatically granted the basic Editor role on your project. The role includes almost all permissions related to the corresponding project, which leaves your account at risk of privilege escalation.
Vulnerable PoC
In this repository, you can find Terraform script and instructions on how to set up a vulnerable testing GCP project using the script. Then you can exploit the vulnerable project by following exploit steps in the README file.
Conclusion
References
- https://cloud.google.com/storage/docs/access-control/signed-urls
- https://cloud.google.com/storage/docs/access-control/signing-urls-with-helpers
- https://cloud.google.com/iam/docs/understanding-roles
- https://cloud.google.com/iam/docs/service-accounts
- https://cloud.google.com/resource-manager/docs/organization-policy/restricting-service-accounts
- https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob
- https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/
- https://cloud.google.com/compute/docs/metadata/default-metadata-values#vm_instance_metadata
- https://cloud.google.com/iam/docs/conditions-overview#resources
- https://cloud.google.com/iam/docs/service-account-creds#user-managed-keys
- https://cloud.google.com/blog/products/storage-data-transfer/uploading-images-directly-to-cloud-storage-by-using-signed-url
- https://stackoverflow.com/questions/64234214/how-to-generate-a-blob-signed-url-in-google-cloud-run
- https://medium.com/@evanpeterson17/how-to-generate-signed-urls-using-python-in-google-cloud-run-835ddad5366
News & Updates...
We are happy to share our methodology and security guide on how to do security reviews for Ruby on Rails applications through source code. In the article you will get an idea about the architecture and design of Ruby on Rails, present security checklist to increase the coverage for penetration testing assessments, and review how to find and exploit most of the OWASP 10 vulnerabilities.
XSS can be particularly devastating to Electron apps, and can result in RCE and phishing that might not be viable in a browser. Electron has features to mitigate these problems, so applications should turn them on. Even XSS that would be low-impact in the browser can result in highly effective phishing if the application’s URL allowlist is improperly designed. Attacks exploit the Electron model and the application-like presentation of Electron to gain the user’s confidence.