AWS provides SDKs on iOS and Android to upload to their servers yet you don't want your key exposed if it was decompiled. How do you prevent that? Is there a way to sign a URL on the backend and give it to the client so they can upload directly onto S3 Without exposing the key?
You can use Amazon STS (Security Token Service) to generate unique sign-in credentials that also expire automatically.
You can also control permissions on these temporary credentials obtained via STS (for example to allow only upload permissions in a certain S3 bucket).
Related
I have a Laravel application that is hosted on AWS. I am using an S3 bucket to store files. I know that I have successfully connected to this bucket because when I upload files, they appear as I would expect inside the bucket's directories.
However, when I try to use the URL attached to the uploaded file to display it, I receive a 403 Forbidden error.
I have an IAM user set up named laravel which has the permission AmazonS3FullAccess applied to it, and I am using that key/secret.
I have the Object URL like so:
https://<BUCKET NAME>.s3.eu-west-1.amazonaws.com/<DIR>/<FILENAME>.webm
But if I try to access that either in my app (fed into an audio player) or just via the link directly, I get a 403. None of the tutorials I've followed to get this working involve Bucket Policies, but when I've googled the problems I'm having, Bucket Policy seems to come up.
Is there a single source of truth on how I am to do this? My AWS knowledge is very limited, but I am trying to get better!
When you request a URL of the form https://bucket.s3.amazonaws.com/dog/snoopy.png, that request is unauthenticated. Your S3 bucket policy does not allow unauthenticated access to the contents of the bucket so that request is denied with 403.
If you want your files to be downloadable by an unauthenticated/anonymous client then create an S3 bucket policy to allow that.
Alternatively, your server can create signed URLs and share those with the client.
Otherwise, your client's requests need to be authenticated, which means having correctly-permissioned credentials and using an AWS SDK.
Typically, back-end applications that you write that need access to data in S3 (or other AWS resources) would be given AWS credentials allowing the necessary access. If your back-end application runs in AWS then you would do that by launching the compute with an IAM role.
Typically, front-end applications would not have AWS credentials. Instead they would either authenticate to a back-end that then does work with AWS resources on their behalf. There are other options, however, such as AWS Amplify apps.
Am writing an instagram type image/video sharing app in flutter that uses Firebase for auth (Google/Facebook/Apple/Twitter). As Firebase storage services are very pricey, I want to use cheaper option of AWS S3. So, once the user is authenticated, the app should be able to -
Uplaod the AWS S3 bucket - but in a secure manner. If I use pre-signed URL, I'll still need to store access key Id in the app, which is not very secure IMO
Read the files from the S3 - same issue as above
One user should not be able to see other user's file or manipulate them in any way - I guess signed URL will help here too
In short - how to securely access S3 bucket via a mobile app when the user has been authenticated using Firebase
I'm trying to make javascript access Amazon S3 bucket, and everything works as expected. I need to secure the javascript sothat I dont store the accessKeyId and secretAccessKey in code or TFS. Below is the bit which passess the access and secret keys.
AWS.config.update({
region: '--region-code-here--',
accessKeyId: '--keyhere--',
secretAccessKey: '--secretkey-here--'
});
const s3 = new AWS.S3();
//... more code...
According to amazon https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-browser.html, the suggested way is to Using Amazon Cognito Identity or Using web federated identity than hardcoded in the script. I find it hard to follow the amazon documentation in my S3 context.
Accessing S3 via javascript is part of a larger application, and I cannot prompt the user for separate credentials for the JS to access the S3 bucket.
Any tips very much appreciated. The ultimate goal is to secure the access key being hardcoded.
Assuming your JavaScript code is running in a web page, your app will not be able to access your S3 bucket unless it has credentials or you make the bucket public. Assuming you don't want to make the bucket public, you need to find a way to get credentials to the app.
Typically you would want to authenticate the user before you hand out credentials (because those credentials will be visible in the app) and you can do both with a dedicated server application. Or you can do this more easily with Cognito or WIF, which will authenticate the client and convert that into a set of credentials for a given IAM role. Or, of course, you could ask the user to supply AWS credentials, but I'm assuming that's not appropriate in this case.
I'm trying to make a private bucket on AWS s3 and read and write to it from an Android App.
I found many of resources and questions but nothing of it gave me a complete answer.
I made a private one but don't know what should I write in Bucket Privacy, and what I need to access it from an Android app.
How can I do it?
More details:
My app is an e-commerce app has users, they upload photos to the app and view it from a website and from the app too.
All data on my server except photos, I want to upload the photos to a private bucket on s3 and view those by URLs saved on my server. Can I do it?
Restrict access to IAM role for S3 bucket. Use this role in Android App.
The normal architecture for this is:
Keep the Amazon S3 bucket private (no Bucket Policy)
Users of the Android app provide their login information to the app, which authenticates against your back-end service
Once authenticated, your back-end service can generate temporary credentials using AWS Security Token Service (STS) — permissions are assigned to these credentials that grant access to Amazon S3 (eg only for a certain path within a particular bucket)
The mobile app can then use these temporary credentials to directly communicate with Amazon S3 to upload/download objects
You could use Amazon Cognito for authentication and provisioning of credentials, or you could code your own authentication process (eg checking against your own database).
References:
Using Amazon Cognito for Mobile Apps - AWS Identity and Access Management
AWS IAM Now Supports Amazon, Facebook, and Google Identity Federation | AWS News Blog
About SAML 2.0-based Federation - AWS Identity and Access Management
If you only wish to view photos, then a simpler method would be for the back-end to generate Amazon S3 pre-signed URLs, which permit time-limited access to private objects in Amazon S3.
See: Amazon S3 pre-signed URLs
You can do this both by:
creating a bucket policy for specific IAM user
creating an ACL policy for an account and then delegating permissions to a specific user
I have created a static website which is hosted in S3.
Now I need to upload a file to another S3 bucket via that frontend.
For that I am using AWS library.
Problem is I have to give the AWS access keys to the AWS library.
As hardcoding the credentials is a bad practice, what can I do to securely pass the access keys to the AWS library?
Use AWS JavaScript SDK to call the sts:assumerole to get the temporary credentials that will be valid for certain time instead of hard-coding them in your code.
Once you get the Access key and secret key along with the SessionToken use them in AWS Library and the credential will be valid for 1 hour by default, if duration is not specified while calling assume role api.
Hope this helps