Amazon S3 Securing Static Website - amazon-web-services

I'm looking for a combination of policies to access a static website in a S3 bucket only with a certain token/sign string.
I mean, is it possibile to make the static website not readable by everyone by default but temporary accessible with something like http://mybucket.s3-website-location.amazonaws.com/myfolder/index.html?sign=XXXXX?
With this call you should also have access to all the tree in the "myfolder" folder.

I don't think its possible - think about how you would do that on a regular website, you would need to read the querystring and then do some sort of lookup/logic to determine if the token was valid, i.e. you need to do some server-side processing to carry out that logic.
Once you need to add server-side logic you are no longer have a 'static' website (even though ultimately you may be serving up static pages). S3 may not be the right solution for you in this case.
From aws: http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html
You can host a static website on Amazon S3. On a static website, individual web pages include static content. They may also contain client-side scripts. By contrast, a dynamic website relies on server-side processing, including server-side scripts such as PHP, JSP, or ASP.NET. Amazon S3 does not support server-side scripting.

You can only do this for a single URL at a time, using a signed S3 URL with an expiration time. There is no way to create a signature that can be appended to any of a group of URLs that will make them all work with the signature, but not work without it.
Sorry.
However, this is fairly easy to do with an actual website as a front end. You'd have to code the website to redirect every request to a signed URL specific to that object. To do that, you'd need an EC2 instance that runs the code you write. But as of now, S3 doesn't have a way to do this all by itself.

Related

How to host images stored inside S3 static website, over HTTPS?

I have an S3 bucket which I'm using for storing images uploaded by users. Then I save paths to those images in my database, each path looks like so https://bucket-name.s3.eu-central-1...
I then added an image resizing feature which requires the S3 bucket to be a static website, so that redirection rules can be used.
Appearantly this static website thingy made it impossible to download those pictures using old paths with https protocol, and because my website is using https - I can't make http requests. So now all the profile pictures of the users aren't displayed at all.
I'm looking for a solution to this problem. I can change pictures' paths stored in the database if needed.
One possible solution I have in mind is using a subdomain with CloudFront, e.g. pictures.my-website.com/name-of-the-picture.png
Do you think it'll work and it's a good solution, or there is a better way?
Use CloudFront as a server with predefined domain and SSL certificates https://medium.com/#tsubasakondo_36683/serve-images-with-cloudfront-s3-8691d5c387b6

How to do URL masking with Django?

On a Django 1.9 project I need to redirect:
https://example.com/app/
to
https://examplebucket.s3.amazonaws.com/app/index.html
But I need https://examplce.com/app/ to be still visible on the browser address bar...
I know this must be possible in theory with Django because the previous team working on this project did a setup to serve the /static/ media files from an S3 bucket. And if I access those static files via https://example.com/static/app/index.html, they are served from the S3 bucket but the browser address bar still shows the original url I input.
I'm deploying an Ionic Browser project and I want the files (including the index) to be served from the S3 but the url needs to be user friendly, thats the reason.
The old (dirty) way of doing this is frame-based forwarding.
You set up an iframe on a page in /app/ which points at the real app, letting the url stay the same.
It's not considered a good practice because of security issues (can't be sure where you are typing credentials into), and bookmarking issues (url is always the same so can't bookmark inner pages).
Another alternative is to set up a proxy script that just takes the url, turns that into the equivalent aws url, downloads it and then returns it. This would break the benefits of your cloud hosting if it has multiple regions... it would always be passed through the bottleneck of your server.

What is difference between aws s3 virtual-hosted–style URL V/s path-style URL

AWS S3 provides 2 styles of paths for accessing S3 objects.
Are there any reasons for which style should be used when?
In a virtual-hosted–style:
http://bucket.s3.amazonaws.com
http://bucket.s3-aws-region.amazonaws.com.
In a path-style URL :
http://s3.amazonaws.com/bucket
http://s3-aws-region.amazonaws.com/bucket
There's quite a bit of information regarding this in the Virtual Hosting of Buckets section of the AWS docs.
Besides the attractiveness of customized URLs, a second benefit of virtual hosting is the ability to publish to the "root directory" of your bucket's virtual server. This ability can be important because many existing applications search for files in this standard location. For example, favicon.ico, robots.txt, crossdomain.xml are all expected to be found at the root.
In short, when using the virtual hosted style you will have your files at the root directory. This means you are accessing the top level of what is basically a file structure for your domain which is handy when dealing with some applications that will search your domain at this root level for certain things such as a favicon (the little icon on the tab of the page in your browser).
Other advantages include generally having a neater looking domain. This is almost always the better option when it comes to domains unless you simply want your bucket for personal use where most of this wouldn't matter.

Restricting access to static files in Django/Nginx

I am building a system that allows users to generate a documents and then download them. The documents are PDFs (not that it matters for the sake of this question) and when they are generated I store them on my local file system that the web server is running on with uuid file names
c7d43358-7532-4812-b828-b10b26694f0f.pdf
but I know "security through obscurity" is not the right solution ...
I want to restrict access to they files on a per account basis if possible. One thing I think I could do is upload them to S3 and provide a signed URL, but I want to avoid that for now if possible.
I am using Nginx/Django/Gunicorn/EC2/S3
What are some other solutions?
If you are serving small files, you can indeed use Django to serve them directly, writing the file into the HttpResponse object.
If you're serving large files however, you might want to leave that task to your webserver, you can use the X-Accel-Redirect header on Nginx (and X-Sendfile for Apache & Lighttpd) to have your webserver serve the file for you.
You can find more information about the header itself in Nginx's documentation here, and you could find some inspiration as to how to use that in Django here.
Once you're done sending files through Django views, enforcing user authentication should be pretty straightfoward using Django's auth framework.
How about enforcing user==owner at the view level, preventing access to the files, storing them as FileFields, and only retrieving the file if that condition is met.
e.g. You could use the #login_required decorator on the view to allow access only if logged in. This could be refined using request.user to check against the owner of the file. The User Auth section of the Django documentation is likely to be helpful here.
The other option, as you mention is via S3 itself, generating urls within Django which have a querystring allowing an authenticated user access to download a particular s3 object with a time limit. Details on that can be found at the s3 documentation. A similar question has been asked before here on SO.
I've used django-private-files with great success, it enforces protection at the view level and uses differente backends to do the actual file transfer.

Django: control access to "static" files

Ok, I know that serving media files through Django is a not recommended. However, I'm in a situation where I'd like to serve "static" files using fine-grained access control through Django models.
Example: I want to serve my movie library to myself over the web. I'm often travelling and I'd like to be able to view any of my movies wherever I am, provided I have internet access. So I rip my DVDs, upload them to my server and build this simple Django application coupled with some embeddable video player.
To avoid any legal repercussions, I'd like to ensure that only logged-on users with the proper permissions (i.e. myself and people living in the same household, which can, like me, access the real DVDs at their convenience), but denies it to other users (i.e. people who posted comments on my blog) and returns an HTTP 404.
Now, serving these files directly using Apache and mod_wsgi is rather troublesome because when an HTTP request for the media files (i.e. http://video.mywebsite.com/my-favorite-movie/) comes in, I need to validate against my user database that the person at the other end has the proper permissions.
Question: can I achieve this effect without serving the media files directly through a Django view? What are my options?
One thing I did think of is to write a simple script that takes a session ID and a video's slug and returns some boolean indicating if the user may (or may not) access the video file. Then, somehow request mod_wsgi to execute this script before accessing the requested URL and return an HTTP 404 if the script failed. However, I don't have a clue if this is even possible.
Edit: Posting this question clarified some of my ideas for search and I've come across mod_python's file wrapper extension. Does anyone have enough experience with that to validate that it is a viable solution?
Yes, you can hook into Django's authentication from Apache. See this how-to:
Authenticating against Django’s user database from Apache