Source URL: https://cloud.google.com/blog/products/identity-security/best-practices-to-prevent-dangling-bucket-takeovers/
Source: Cloud Blog
Title: Secure your storage: Best practices to prevent dangling bucket takeovers
Feedly Summary: Storage buckets are where your data lives in the cloud. Much like digital real estate, these buckets are your own plot of land on the internet. When you move away and no longer need a specific bucket, someone else can reuse the plot of land it refers to — if the old address is still accessible to the public.This is the core idea behind a dangling bucket attack. It happens when you delete a storage bucket, but references to it still exist in your application code, mobile apps, and public documentation. An attacker can then simply claim the same bucket name in their own project, effectively hijacking your old address to potentially serve malware and steal data from users who unknowingly still rely on a bucket that is no longer officially in use.Fortunately, you can protect your applications and users from this threat with the following four steps.First, implement a safe decommissioning planWhen you delete a bucket, do so carefully. A deliberate decommissioning process is critical. Before you type gcloud storage rm, follow these steps:
Step 1: Audit and learnBefore deleting anything, take the time to understand who and what are still accessing the bucket. Use logs to check for recent traffic. If you see active traffic requests coming from old versions of your app, third-party services, and users, investigate them. Pay extra attention to requests attempting to pull executable code, machine learning models, dynamic web content (such as Java Script), and sensitive configuration files.You might see a lot of requests coming from bots, data crawlers, and scanners by checking the user agent of the requester. Their requests are essentially background noise, and don’t indicate that the bucket is actively required for your systems to function correctly. These are not dangerous and can be safely disregarded because they don’t represent legitimate traffic from your applications and users.Step 2: Delete with confidenceMany automated processes and user activities don’t happen every day, so it’s important to wait at least a week before deleting the bucket. Waiting for at least a week increases the confidence that you’ve observed a full cycle of activity, including:Weekly reports: Scripts that generate reports and perform data backups on a weekly schedule.Batch jobs: Automated tasks that might only run over the weekend or on a specific day of the week.Infrequent user access: Users who may only use a feature that relies on the bucket’s data once a week.After you’ve verified that no legitimate traffic is hitting the bucket for at least a week, and you’ve updated all of your legacy code, then you can proceed with deleting the bucket. Deleting a Google Cloud project effectively deletes all resources associated with it, including all Google Cloud Storage buckets.Next, find and fix code that references dangling bucketsPreventing future issues is key, but you may have references to dangling buckets in your environment right now. Here’s a plan to hunt them down and fix them.Step 3: Proactive discoveryAnalyze your logs: This is one of your most powerful tools. Query your Cloud Logging data for server and application logs showing repeated 404 Not Found errors for storage URLs. For example, a high volume of failed requests to the same non-existent bucket name is a major red flag (and to remediate it, we recommend you continue with Step 3 and then proceed to Step 4.)Scan your codebase and documentation: Perform a comprehensive scan of all your private and open-source code repositories (including old and archived ones), configurations, and documentation for any references to your storage bucket names that may no longer be in use. One of the ways to find them is to look for the following patterns:gs://{bucket-name}storage.googleapis.com/{bucket-name}{bucket-name}.storage.googleapis.comcommondatastorage.googleapis.com/{bucket_name}{bucket_name}.commondatastorage.googleapis.comYou can find whether a bucket still exists by querying https://storage.googleapis.com/{your-bucket-name}. If you see response NoSuchBucket, it means you identified a dangling bucket reference.
code_block
If the bucket exists (and you do not get a NoSuchBucket error), you should verify that it actually belongs to your organization — a threat actor may have already claimed the name.The easiest way to check for ownership is to try to read the bucket’s Identity and Access Management (IAM) permissions.If you run a command like gcloud storage buckets get-iam-policy gs://{bucket-name} and receive an Access Denied or 403 Forbidden error, this is a sign bucket is claimed by someone else. It proves the bucket exists, but your account doesn’t have permission to manage it — indicating it has been taken over. This reference should be treated as a risk and be removed.For your convenience, we provide a script below that can find dangling references in a given file.
code_block
<ListValue: [StructValue([(‘code’, ‘import re\r\nimport sys\r\nfrom typing import Optional, Set\r\n\r\nimport requests\r\nfrom requests.exceptions import RequestException\r\n\r\ndef check_bucket(bucket_name: str) -> Optional[requests.Response]:\r\n try:\r\n with requests.Session() as session:\r\n response = session.head(f”https://storage.googleapis.com/{bucket_name}")\r\n return response\r\n except RequestException as e:\r\n print(f"An error occurred while checking bucket {bucket_name}: {e}")\r\n return None\r\n\r\n\r\ndef sanitize_bucket_name(bucket_name: str) -> Optional[str]:\r\n # Remove common prefixes and quotes\r\n bucket_name = bucket_name.replace("gs://", "")\r\n bucket_name = bucket_name.replace("\\"", "")\r\n bucket_name = bucket_name.replace("\\\’", "")\r\n bucket_name = bucket_name.split("/")[0]\r\n\r\n # Validate the bucket name format according to GCS naming conventions\r\n if re.match("^[a-z0-9-._]+$", bucket_name) is None:\r\n return None\r\n return bucket_name\r\n\r\n\r\ndef extract_bucket_names(line: str) -> Set[str]:\r\n all_buckets: Set[str] = set()\r\n\r\n pattern = re.compile(\r\n r\’gs://([a-z0-9-._]+)|\’\r\n r\'([a-z0-9-._]+)\\.storage\\.googleapis\\.com|\’\r\n r\’storage\\.googleapis\\.com/([a-z0-9-._]+)|\’\r\n r\'([a-z0-9-._]+)\\.commondatastorage\\.googleapis\\.com|\’\r\n r\’commondatastorage\\.googleapis\\.com/([a-z0-9-._]+)\’,\r\n re.IGNORECASE\r\n )\r\n\r\n for match in pattern.finditer(line):\r\n # The first non-empty group is the bucket name\r\n if raw_bucket := next((g for g in match.groups() if g is not None), None):\r\n if sanitized_bucket := sanitize_bucket_name(raw_bucket):\r\n all_buckets.add(sanitized_bucket)\r\n\r\n return all_buckets\r\n\r\n\r\ndef main(filename: str) -> None:\r\n with open(filename, \’r\’) as f:\r\n for i, line in enumerate(f, 1):\r\n bucket_names = extract_bucket_names(line)\r\n for bucket_name in bucket_names:\r\n response = check_bucket(bucket_name)\r\n if response.status_code == 404:\r\n print(f"Dangling bucket found: {bucket_name} (line {i}), {line}")\r\n\r\n\r\nif __name__ == "__main__":\r\n if len(sys.argv) != 2:\r\n print("Usage: python find_dangling_buckets.py <filename>")\r\n sys.exit(1)\r\n \r\n main(sys.argv[1])’), (‘language’, ”), (‘caption’, <wagtail.rich_text.RichText object at 0x3ef76a4bb3a0>)])]>
Please be aware that this script and recommendations can only find hardcoded references, not those generated dynamically during runtime. Also, codebase might have hardcoded bucket names that do not follow the pattern but are being used by Google Cloud Storage clients.Step 4: Reclaim and secureIf you find a dangling bucket name that might represent security risk to you or your clients, act fast.If you do not own the dangling bucket:Use all available data from the previous step to find dangling buckets and remove any hardcoded references in your code or documentation. Deploy the fix to your users to permanently resolve the issue.If you own the dangling bucket:Reclaim the name: Create a new storage bucket with the exact same name in a secure project you control. This prevents an attacker from claiming it.Lock it down: Apply a restrictive IAM policy to the reclaimed bucket. Deny all access to allUsers and allAuthenticatedUsers and enable Uniform Bucket-Level Access. Enable Public Access Prevention control to turn the bucket into a private "sinkhole."By building these practices into your development lifecycle and operational procedures, you can effectively close the door on dangling bucket takeovers. Securing your cloud environment is a continuous process, and these steps will add powerful layers of protection for you and your users.To learn more about managing storage buckets, you can review our documentation here.
AI Summary and Description: Yes
Summary: The text discusses the security risks associated with “dangling buckets” in cloud storage and provides a structured approach to mitigate such vulnerabilities. This is particularly relevant for security professionals in cloud computing, as it outlines proactive measures to prevent the hijacking of inactive cloud storage resources.
Detailed Description:
The centerpiece of the text is the phenomenon of dangling bucket attacks, which occur when storage buckets in cloud services are deleted, but references to them persist in application code, mobile apps, or documentation. Attackers can exploit these residual references to hijack the bucket names, resulting in possible data theft or malware deployment.
Key points include:
– **Understanding Dangling Buckets**:
– A dangling bucket attack occurs when a deleted storage bucket’s name is reused by an attacker.
– Users still trying to access the former bucket can fall victim to malware or data exfiltration.
– **Protective Measures**:
1. **Safe Decommissioning Plan**:
– Before deleting a bucket, conduct an audit to check if any services or users still access it.
– Examine logs for recent traffic to ascertain legitimate use.
2. **Deletion Process**:
– Wait for a week post-audit to ensure no legitimate activity is occurring.
– Confirm that all legacy code is updated to prevent references to the deleted bucket.
3. **Proactive Discovery**:
– Regularly analyze logs for 404 errors indicating attempts to access non-existent buckets.
– Conduct comprehensive scans of codebases and documentation to identify lingering references.
4. **Reclaiming and Securing**:
– If you own a dangling bucket, reclaim the name by creating a new bucket with the same name in a secured environment.
– Apply restrictive IAM policies and prevent public access to mitigate any risks.
– **Technical Implementation**:
– The text includes a Python script to identify hardcoded bucket references in code, highlighting the importance of securing codebases against this vulnerability.
Through these strategies, the text emphasizes the necessity of incorporating security practices into the development lifecycle, extending continuous efforts to safeguard cloud environments. Security and compliance professionals should regard this advisory as a critical guideline for mitigating risks associated with cloud storage.