Matt Bacchi
Posted on January 30, 2024
There's been a recent uptick in the number of S3 buckets that have become "hijacked" or "taken over".
How can an attacker take over your S3 bucket? What can you do to prevent this on your buckets?
We'll answer these questions and provide details on how you can neutralize the threat of S3 bucket takeovers.
What is Hijacking?
How can your S3 bucket get hijacked?
It should be noted that the term "hijacked" is a misnomer. S3 buckets which have ended up in this state were managed poorly by the owner. The original owner had to choose to give up ownership of the S3 bucket, prior to it being claimed by a bad actor. If you have an active AWS S3 bucket in your account, this cannot occur unless you relinquish control. These are categorized as software supply chain attacks, where the attacker hijacks open source software or software updates, eventually compromising target computers.
AWS uses a global namespace for S3 buckets. If a bucket name "mattbacchi" is available and I requisition it, no one else in the world can use that bucket name. A global namespace has some downsides, namely that everyone competes for the same bucket names, and a single bucket name cannot be owned by more than one AWS account.
This surge in exploit/hijack/takeover incidents ultimately has this global namespace to blame. If you owned an S3 bucket but then deleted it, someone else could subsequently recreate it in their account (after a short period of time.)
If the deleted bucket was public and contained trusted files (such as npm packages), someone with sinister intentions could recreate the bucket and masquerade as you. If they named their tainted files the same as your trusted files, users might download the malicious content assuming it was your original content. This is how the above poisoned "bignum" npm package exploit worked. The S3 bucket owned by someone the "bignum" software developer trusted was abandoned, subsequently an attacker recreated it with malicious content.
These attacks cannot occur if S3 buckets are managed with better data lifecycle hygiene.
Preventing S3 Bucket Takeover
In order to neutralize this threat, I recommend never deleting your S3 buckets.
As described above, the only S3 buckets vulnerable to this attack vector are those that have been deleted and are no longer active. The logical defense is to never relinquish your S3 buckets, instead you maintain the bucket and name forever.
Won't this get expensive, you may ask? AWS bills customers for S3 based on storage. If you aren't storing any data in the bucket, it will never generate a charge. In this way we retain an S3 bucket name so that it doesn't fall into the wrong hands.
Of course, this may not be necessary for all S3 buckets you own. I recommend using this technique for any buckets that are public and have been used in production software applications. The "bignum" npm package bucket above is a prime example, retaining that bucket would have prevented the attack.
Decommissioning Process
Developing an official process to manage this in your organization is important.
If you intend to retain your S3 buckets in order to prevent takeover, you must first develop documentation and communicate this policy. Also consider how you will implement identifiers or signposts indicating the bucket must be retained to administrators who may not be familiar with the process. I've personally used documentation, an AWS tagging scheme, and a couple other methods to prevent the bucket from being accidentally relinquished.
One method of making this obvious to infrastructure engineers (i.e. devops or platform engineers) is to create a zero byte file in the bucket that identifies it as persistent. I have suggested the file be named DO_NOT_DELETE_S3_BUCKET_PERSISTENT
as a fairly large signpost for people to prevent them from deleting it. A sample command to do this via the AWS CLI is something like:
touch DO_NOT_DELETE_S3_BUCKET_PERSISTENT; aws s3 cp DO_NOT_DELETE_S3_BUCKET_PERSISTENT s3://BUCKETNAME/
Another method is to create an AWS tag on the bucket such as persistent=true
.
Finally, if you want to use a more durable mechanism, add an S3 bucket policy that denies the action s3:DeleteBucket
as well as s3:PutObject
. This will prevent removing the bucket unless the user is an administrator, at which point they can remove the s3:DeleteBucket
permission from the bucket policy. But they must manually perform this update, and hopefully that extra step makes them realize it shouldn't be deleted.
Conclusion
Today we've discussed the cause of S3 bucket hijacking and some methods of preventing it. Hopefully this motivates you to perform some analysis of your S3 buckets and apply these suggestions in your environment.
Thanks for reading and have a great day!
Posted on January 30, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.