I have developed a react native app, with AWS Amplify to support the backend (DynamoDB, S3). All users of the app have to use Auth.signIn() to sign in and are part of a user pool.
Once in, they can start to upload videos to S3 via the app or view videos in the app that are in the S3 bucket that is PUBLIC.
I use the path to the S3 video (https://myS3bucket....) as the source URL of the video. However the videos are only visible in my app when the bucket is public. Any other setting (protected/private) and no video is visible. How can i make this more secure?
S3 Buckets have 3 methods of managing security:
IAM: Any user or role within the same AWS account as the bucket can be granted permissions to interact with the S3 Bucket and its objects.
S3 Bucket Policies: Grant bucket wide (or prefix) access to S3 buckets.
S3 ACLs - Per object level permissions.
Its generally advised against using S3 ACLs these days as their functionality was improved via S3 bucket policies. Only use them if you need a specific object to have a different set of permissions.
I sugeest not to make files or the bucket public if you want authenticated users to upload and/or download files. For this, use S3 signed URLs to give users access to files. In other words, the backend will authenticate users accordingly, generate them signed URLs and then the react native app will interpret that URL accordingly, ie a video file.
You will need to change a few things but this guide should cover that
I have recently published an article which describes in detail the security best practices, which help address the following points:
How to secure an S3 buckets, which store sensitive user data and the application code.
How to securely configure a CloudFront distribution.
How to protect frontend apps against common OWASP threats with CloudFront Functions.
To learn more have a look at the article.
Best,
Stefan
Related
I am created a lambda trigger , when a video file uploaded in a s3 input bucket, it will create a thumbnail in output bucket, but I don't know how to access it. Please help me.
Iam generating 3 thumbnail from a single video, in this bottom image 👇, there this 4 video.
But I have the name of the file as dfdf and treasersonthing and
vijay.treaser.ve and vollyball , but I want all 3 images using this
file name.
The question is quite open - do you want to access the generated thumbnails on the frontend of your website? If so, I will try and provide some ideas for the architecture, based on some assumptions.
Publicly Accessible Thumbnails
Assuming you want to make the thumbnails publicly accessible, S3 can expose them through its own HTTP endpoint. See AWS documentation. Please note that this involves enabling Public Access on your bucket, which can potentially be risky. See How can I secure files in my Amazon S3 bucket for more information. While this is an option, I'm not going to elaborate on it, as it's probably not the best.
The preferred way is to have a CloudFront distribution serve files from your S3 bucket. This has the advantages of a typical CDN - you can have edge locations caching your files across the globe, thus reducing the latencies your customers see. See this official guide on how to proceed with this CloudFront + S3 solution.
Restricted-access Thumbnails
If your thumbnails are not meant to be public, then you can consider two options:
implement your own service (hosted on any compute engine you prefer) to handle the authentication & authorization, then return the files to your customers, or
use the CloudFront + S3 solution and control the authentication and authorization with Lambda#Edge. See AWS docs.
I am creating a web app using React where the user can upload files to a folder in my S3 bucket. This folder will have a unique passcode name. The user (or someone else) can use this passcode to retrieve these files from the S3 folder. So basically there is no login/authentication system.
My current issue is how do I safely allow read/write access to my S3 bucket? Almost every tutorial stores the access keys to the client code which I read is very bad practice but I also don't want to create a backend for something this simple. Someone suggested presigned URLs but I have no idea how to set that up (do I use Lambda? IAMs?). I'm really new to AWS (and webdev in general). Does anyone have any pointers on what I could look into?
do I use Lambda? IAMs?
The setup and process if fully explained in AWS blog:
Uploading to Amazon S3 directly from a web or mobile application
I have a social media app deployed on App Engine where users can upload and share photos/videos with a private group of people. For writes, I have a POST endpoint that accepts uploaded files and writes them to one GCS bucket that's not public. For reading, a GET endpoint checks with Cloud SQL if this user is authorized to access the media file - if yes, it returns the file stream. The file is stored only for 48 hours and average retrieval is 20 times per day. Users are authenticated using Firebase email link login.
The issue with the current approach is that my GET endpoint is an expensive middleman for reading the GCS file stream and passing it on to the clients, adding to the cost as may times the API is invoked.
There's no point caching the file on App Engine because cache hit ratio will be extremely low for my use case.
The GET API could return a GCS file URL instead of File Stream, if I make the GCS bucket public. But that would mean anyone can access the file with this public URL, not just my app or limited user. Plus, the entire bucket is vulnerable now.
I could create an ACL for each GCS file object, but ACLs work only for users with Google accounts and my app uses email link authentication. There's also a limit on ACL entries per object in case the file needs to be shared with more than 100 people.
The last option I have is to create a signed link that works for a short duration, enabling limited unauthorized sharing.
Also tagging Google Photos. In case the partner sharing program can help with this problem, then I can migrate from GCS to Google Photos for storage.
This looks like a common use-case for media based apps. Are there any recommended design patterns to achieve the goal in a cost effective way?
This is my first week learning GCP, so I maybe wrong in some of the points shared above.
I would like to create a public read aws s3 bucket with some files read restricted by a IAM role.
First of all:
I using amplify cli for deploying my «static» website.
The website is a react app
This app have public pages/react components and a admin area
I would like to restrict admin area/admin pages/admin react components with a aws IAM role
More details:
The react app is very big so I splited components using asyncComponent feature like const Dashboard = asyncComponent(() => import('./pages/Dashboard'))
So when I build the app instead to have one big file I have several small files. And all these files are on the same bucket.
Now I want to build admin pages. Always using asyncComponent we get a collection of «Admin» files and there are hosted on the same bucket. But for security reason I want to restrict access to authenticated users with a certain IAM role (for ex AdminRole).
I go through lot of doc from amplify config or AWS::S3::Bucket from cloudFormation and I saw different things that tell me it's possible but I'm very lost in this doc.
So finally I ask:
How can I protect some files/objects for reading access in s3 buckets with a IAM role?
And how can I «tag» admin components in the react app? or via amplify? maybe using regex for match files? or a specified folder? In order to apply this read restriction.
Thank you in advance for your reply.
Content in Amazon S3 is private by default.
Therefore, anything you are happy for everyone in the world to view can be made publicly accessible via a Bucket Policy (whole bucket or part of a bucket) or via Access Control Lists (ACLs) on the objects themselves.
To serve content that should be restricted to specific users, take advantage of Pre-Signed URLs. These are time-limited URLs that provide temporary access to private objects in Amazon S3. They are easy to generate (no API calls required).
The way it would work is:
Users would authenticate with your application
When they wish to access restricted content, the application would determine whether they are permitted access
If they are permitted access, the application would generate a pre-signed URL. These can also be used in <a> and <img> tags to refer to pages and images.
Users will receive/view the content just like normal web components
Once the expiry time has passed, the pre-signed URLs will no longer work
See: Share an Object with Others - Amazon Simple Storage Service
(I'm not an Amplify person, so I can't speak to how Amplify would specifically generate/use pre-signed URLs.)
I am building an iPhone app that stores user logon credentials in an AWS DynamoDB. In another DynamoDB I am storing locations of files (stored in S3) for that user. What I don't understand is how to make this secure. If I use a Token Vending Machine that gives that application an ID with access to the user DynamoDB, isn't it possible that any user could access the entire DB and just add or delete any information that they desire? They would also be able to access the entire S3 bucket using this setup. Any recommendations on how I could set this up securely and properly?
I am new to user DB management, and any links to helpful resources would be much appreciated.
Regarding S3 and permissions, you may find the answer on the following question useful:
Temporary Credentials Using AWS IAM
IAM permissions are more finegrained than you think. You can allow/disallow specific API calls, so for example you might only allow read operations. You can also allow access to a specific resource only. On S3 this means that you can limit access to a specific file or folder , but dynamodb policies can only be set at the table level.
Personally I wouldn't allow users direct access to dynamodb - I'd have a webservice mediating access to that, although users being able to upload directly to s3 or download straight from s3 is a good thing (Your web service can in general give out pre signed urls for that though)