Node js authentication system for content uploaded to s3 - node.js

I am looking for a solution that will allow me to check if the user has access to files located on s3.
Right now I have only two content status public and private but when one user copy the file URL and the uploader change state to private the first user still get access to this file.
I know I need to create some kind of service to authorize users but I don't know how to return data to them without exposing the s3 url

Related

What is the best practices to save data in private AWS s3 and it's url to mongodb and only authrized user can access the data url?

I'm a new developer trying to figure out the best practices of storing data in AWS s3.
I'm trying to create a website where users can upload their videos or pictures and this will be only accessible to them. If they share the video or picture with another user only then the other user can have read access to it.
So, what I'm planning to do is this,
I want to allow users to upload their data through node js server and nodejs will handle the data uploading in s3 bucket. But here's the main question, How can I get the url of that private object and save to mongodb database. And how can I put the authentication method to the object url to only accessible to the user who put that object or whoever he shared that object to?

Is there a way to store image from the google storage buckets as JPEG locally?

So currently I have images stored in gcp storage.
When I fetch an image, I receive a File object with several parameters. Being one of them mediaLink with a format like https://storage.googleapis.com/download/storage/{path}%{image_name}?generation={value}&alt=media
The problem is that this url is only accessasble with permission, I want to be able to save the image as a JPEG so I can later send it to the user via email.
Is there any way this can be achieved?
Thank you in advance.
To grant access to a object on Cloud Storage for an user without change the bucket to public or require user authentication you may use Signed URLs. With a Signed URl you will be able to share a temporary link to get or upload a file.
More info about here

Shared content from S3 or elsewhere

If you have an app where users have data in S3 buckets but can select who they share it with, what's the best technique for protecting this data? For example, how would Instagram protect their image data if they were using S3 (or some other centralized storage provider) so you could only see pictures you were authorized to see?
Obscurity from large url strings seems like one approach, but I was curious if there was a better technique?
By default, all objects in Amazon S3 are private. You can then add permissions so that people can access your objects. This can be done via:
Access Control List that applies to individual objects
A Bucket Policy that applies rules to the whole bucket
IAM to apply permissions to specific Users and Groups
A Pre-Signed URL that grants temporary access to an individual object
If you wish to "select who to share it with", there are two choices:
If the person is defined as a User in IAM, then assign permissions against that User
If the person is not defined in IAM (eg an Instagram user), then use a pre-signed URL
A Pre-Signed URL grants access to S3 objects as a way of "overriding" access controls. A normally private object can be accessed via a URL by appending an expiry time and signature. This is a great way to serve private content from Amazon S3.
Basically, if the application determines that the user is entitled to access an object in Amazon S3, it can generate a link that provides temporary access to the object. Anyone with that link can access the object, but it will no longer work once the time period has expired.
The pre-signed URL can be generated via the AWS SDK (available for most popular programming languages). It can also be generated via the aws s3 presign command in the AWS Command-Line Interface (CLI).
Pre-signed URLs can even be used within web pages. For example, the HTML might refer to a picture using an <img> tag, where the src is a pre-signed URL. That way, a private picture can be displayed on the page, but search engines would not be able to scrape the picture.

Is it safe to use a link to an image in my AWS S3 bucket on my webpage?

I have an image in my AWS S3 bucket. Is it safe to include this image in my website by placing the AWS URL in an <img> tag? The URL includes parameters such as "Amz-Signature", "Amz-Credential", and "amz-security-token. Could these be used maliciously to get to access other files in my S3 bucket?
Here is an example URL:
https://s3.amazonaws.com/MyBucketName/FileName.jpg?X-Amz-Date=20160126T141139Z&X-Amz-Expires=300&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=Lots_of_letters_and_Numbers2&X-Amz-Credential=MYAMAZON_CREDENTIALS/20160126/us-east-1/s3/aws4_request&X-Amz-SignedHeaders=Host&x-amz-security-token=REALLY_LONG_SECURITYTOKEN
Alternatively, I can generate an expiry URL from my C# code using the AWS SDK. Something like:
var expiryUrlRequest = new GetPreSignedUrlRequest
{
BucketName = WebConfigurationManager.AppSettings["AWSBucketName"],
Key = fileName,
Expires = DateTime.Now.AddHours(3)
};
This yields a URL that has "AWSAccessKeyId" as a parameter.
Are either of these URL's safe to use in my webpage? What risks would be involved in using them on my site?
Thank you very much for your time. Please let me know if you need additional information or if I am being unclear.
EDIT: To provide some further insight into my application, users are uploading a file to an S3 bucket. I'm using SignalR to confirm that the image is in the bucket by displaying the image from S3 on my webpage for the user to see.
Do not make the bucket public. If you do, then potentially user1 could see user2's uploaded files.
You can allow users to retrieve single files for a specific period of time using pre-signed URLs.
Mark the S3 bucket as private.
Use GetPreSignedUrlRequest to generate a pre-signed URL for the file you want the user to download.
Use that URL in your <img> tag.
Using this technique is safe:
The user can only download the file during the timeframe that you permit, until the expiration date (which you set as part of the GetPreSignedUrlRequest call)
The credentials you see in the URL are may be the same as those that were used to create the URL. But they are safe to show the user.
The user cannot download any other files from the bucket.
The URL uses a hashing technique to ensure the URL cannot be modified, nor can it be abused to get other files.
If displaying the access key ID is a concern, you can either (a) create an IAM user specifically for the purpose of downloading the files from S3, or (b) use an IAM role on your EC2 instance to generate the pre-signed URL.
References:
http://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURL.html
First of all, there are two ways of restricting access to the content of a bucket:
Private - users need the AWS credentials to access that file (in the same way as shown in your answer)
Public - everybody can access the content of the bucket (https://myBucket.s3.amazonaws.com/myFolder/myFile.jpg)
If you want other users to access the image (for example by providing a URL for your website), you should mark the bucket as public.
DO NOT post the url with your AWS credentials anywhere!!!

Using WebDav for a Public File Share

The question in brief: How can I set up WebDav so that unauthenticated users can download files with a URL, but can't access a list or make changes to the share?
The long version:
I'm new to WebDav. I'd like to replicate the Dropbox/public folder functionality. That allows any user with the correct URL to download a file, but no unauthenticated user can access a list of the files in the subdirectory or make any changes to the public folder.
I'd like to be able to send my client a URL to a file for download without exposing the whole contents of the share and, importantly, without requiring the client to have a user id and password.
The WebDav directory should also not be alterable or viewable by anyone who doesn't have a user id and password.
The WebDav directory is isolated on my server and I can alter .htaccess files.

Resources