Amazon S3 custom error pages and enabling web hosting on bucket - amazon-web-services

Hi I'll try and keep it brief, hope one of you guys knows the answer and I'm not duplicating content.
At the moment I'm using a bucket to take the strain off my server and upload large user files to amazon. This is then reserved to them when they want it via expiring URLs. When the URL expires the user is sent an XML response to say access is denied, and i want to show them a custom error page.
Here Create my own error page for Amazon S3
and Here http://docs.aws.amazon.com/AmazonS3/latest/dev/CustomErrorDocSupport.html
It says you must enable web hosting on the bucket for custom error pages...
So the question is if I do this then just grant any user permissions to access just the custom error pages will this mess anything up with my current usage scenario?
Or is it as simple as everything else stays the same? The docs seem vague and I dont want to mess up my current system...
Sorry if this is a noob question but everyone with the same problem in my research seems happy with the 'Enable hosting' answer and i just want to be sure...
Cheers all
Ed

It's not possible to combine the two things you're trying to combine: query string authentication and custom error pages.
S3 buckets can be made accessible by two different sets of endpoints, each providing a different set of front-end behaviors.
The REST endpoints provide authentication and private content (and SSL), while the Web site endpoints provide custom error (and index) documents, but the objects must be public in order to be accessible, since the web site endpoint does not support authentication (or SSL).
The differences are explained here:
http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html#WebsiteRestEndpointDiff
In some environments, I use an intermediate reverse-proxy, hosted in EC2, acting as a front-end for S3 (which gives me the additional capability of rewriting portions of the request headers and capturing access logs in real-time) and I suspect this is the most viable mechanism for also providing "friendly" errors -- as my proxy does if the URL is completely missing elements like Signature= in the URL (since that can't possibly be anything but an error) but have not yet implemented anything to capture 403 Forbidden responses and style them up.
I did do some preliminary testing to add a Link: header to the error response (in the proxy), in an attempt to convince the browser to load an XSL stylesheet, but so far that has not proven viable.

Related

Host a serverless contact page using Amazon Cloudfront?

I want to host a serverless contact page on Amazon Cloudfront.
I've followed this tutorial to the tee:
Processing a Contact Form Using AWS Cloudfront...
There are many steps, but the most important things that I would like to highlight that I have done correctly:
I have set the AWS S3 bucket to public, and given public read access
My Cloudfront behavior allows the POST method (which I use in my HTML contact-form and corresponding js)
My Lambda function and my API Gateway send an e-mail to me (so I know that is working!)
Still, when I press submit on my actual website, I get this error:
This XML file does not appear to have any style information associated with it.
Could anyone please suggest to me where I might be going wrong? The website contact form is here.
Under the assumption this is a website endpoint the following appears in the documentation.
Requests supported: Supports only GET and HEAD requests on objects
It looks as though this is not supported for static websites and instead will need to be worked around.

Is it a bad practice to make request to 3rd party service to get token?

Suppose this scenario:
I'm building service which works with user uploads to my AWS S3 account.
Each site using my service must have upload form which uploads directly to S3. In order to do that each site has to sign it's upload form with AWS Signature Version 4.
The problem is signing requires AWSAccessKeyId and AWSSecretAccessKey which i must share to my service user and that's not acceptable.
I thought i can generate all needed signing data on my side and the just reply with that when user(site) asks for it.
So the question is: is that a bad idea in order to sign upload form site(which is going to upload file to my S3) has to make request to my server for signing data(XHR or server side)?
I'm not entirely sure what you're asking, but if you're asking if it's a bad idea to sign the upload yourself on behalf of the individual sites, than the answer is no...with a caveat.
Signing the upload (really, you should just sign the upload URL) is far less of a security risk than providing other domains your access keys. That's what it's there for, to allow anonymous uploads. Signing the request merely gives the site/user permission to upload, but does not take into account who is uploading or what they are uploading.
This is where your own security checks need to come in. If the form is hosted on multiple domains (all uploading to your S3 bucket), you should first check the domain the form originated from so as to avoid someone putting the form on their own webserver and trying to upload stuff. Depending on how your various sites are configured, there are a couple of ways to do this, of which I am no expert unfortunately.
Secondly, you will want to validate the data being uploaded. Is it pure text, binary, etc.? You will want to validate all of that prior to initiating the upload.
I hope this helps.

Improvements on cookie based session management

"Instead of using cookies for authorization, server operators might
wish to consider entangling designation and authorization by treating
URLs as capabilities. Instead of storing secrets in cookies, this
approach stores secrets in URLs, requiring the remote entity to
supply the secret itself. Although this approach is not a panacea,
judicious application of these principles can lead to more robust
security." A. Barth
https://www.rfc-editor.org/rfc/rfc6265
What is meant by storing secrets in URLs? How would this be done in practice?
One technique that I believe fits this description is requiring clients to request URLs that are signed with HMAC. Amazon Web Services offers this technique for some operations, and I have seen it implemented in internal APIs of web companies as well. It would be possible to sign URLs server side with this or a similar technique and deliver them securely to the client (over HTTPS) embedded in HTML or in responses to XMLHttpRequests against an API.
As an alternative to session cookies, I'm not sure what advantage such a technique would offer. However, in some situations, it is convenient or often the best way to solve a problem. For example, I've used similar techniques when:
Cross Domain
You need to give the browser access to a URL that is on another domain, so cookies are not useful, and you have the capability to sign a URL server side to give access, either on a redirect or with a long enough expiration that the browser has time to load the URL.
Examples: Downloading files from S3. Progressive playback of video from CloudFront.
Closed Source Limitations
You can't control what the browser or other client is sending, aside from the URL, because you are working with a closed source plugin of some kind and can't change its behavior. Again you sign the URL server side so that all the client has to do is GET the URL.
Examples: Loading video captioning and/or sprite files via WEBVTT, into a closed-source Flash video player. Sending a payload along with a federated single sign-on callback URL, when you need to ensure that the payload can't be changed in transit.
Credential-less Task Worker
You are sending a URL to something other than a browser, and that something needs to access the resource at that URL, and on top of that you don't want to give it actual credentials.
Example: You are running a queue consumer or task-based worker daemon or maybe an AWS Lambda function, which needs to download a file, process it, and send an email. Simply pre-sign all the URLs it will use, with a reasonable expiration, so that it can perform all the requests it needs to without any additional credentials.

privacy on Amazon S3

I have an app that lets users post and share files, and currently it's my server that serves these files, but as data grows, so I'm investigating using Amazon S3. However, I use dynamic rules for what is public and what is private between certain users etc, so the server is the only possible arbiter, i.e. permissions cannot be decided on the app/client end.
Simplistically, I guess I can let my server GET data from S3, then send them back to the app. But obviously then I'm paying for bandwidth twice not to mention making my server do unnecessary work.
This seems like a fairly common problem, so I wonder how do people typically solve this problem? (Like I read that Dropbox stores its data on S3.)
We have an application with pretty much the same requirements, and there's a really good solution available. S3 supports signed, expiring S3 URLs to access objects. If you have a private S3 object that you, but not others, can access, you can create such a URL. If you give that URL to someone else, he or she can use it to fetch the object that they normally have no access to.
So the solution for your use case is:
User does a GET to the URL on your web site
Your code verifies that the user should be able to see the object (via your application's custom, dynamic rules)
The web site returns a redirect response to a signed S3 URL that expires soon, say in 5 minutes
The user's web browser does a GET to that signed S3 URL. Since it's properly signed and hasn't yet expired, S3 returns the contents of the object directly to the user's browser.
The data goes from S3 to the user without ever traveling back out through your web site. Only users your application has authorized can get the data. And if a user bookmarks or shares the URL it won't work once the expiration time has passed.

What is the threat model for the same origin policy?

http://en.wikipedia.org/wiki/Same_origin_policy
The same origin policy prevents a script from one site talking to another site. Wiki says it's an "important security concept", but I'm not clear on what threat it prevents.
I understand that cookies from one site should not be shared with another, but that can be (and is) enforced separately.
The CORS standard http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing provides a legitimate system for bypassing the same origin policy. Presumably it doesn't allow whatever threat the same origin policy is designed to block.
Looking at CORS I'm even less clear who is being protected from what. CORS is enforced by the browser so it doesn't protect either site from the browser. And the restrictions are determined by the site the script wants to talk to, so it doesn't seem to protect the user from either site.
So just what is the same origin policy for?
The article #EricLaw mentions, "Same Origin Policy Part 1: No Peeking" is good.
Here's a simple example of why we need the 'same origin policy':
It's possible to display other webpages in your own webpage by using an iframe (an "inline frame" places another HTML document in a frame). Let's say you display www.yourbank.com. The user enters their bank information. If you can read the inner HTML of that page (which requires using a script), you can easily read the bank account information, and boom. Security breach.
Therefore, we need the same origin policy to make sure one webpage can't use a script to read the information of another webpage.
The purpose of the same origin policy is to avoid the threat of a malicious site M reading information from trusted site A using the authority (i.e. authorization cookies) of a user of A. It is a browser policy, not a server policy or an HTTP standard, and is meant to mitigate the risk of another browser policy—sending cookies from site A when contacting site A.
Note that there's nothing to stop M from accessing A outside of a browser. It can send as many requests as it wants. But it won't be doing so with the authority of an unknowing user of A, which is what might otherwise happen in the browser.
Also note that the policy prevents the M page from reading from A. It does not protect the A server from the effects of the request. In particular, the browser will allow cross-domain POSTS—cookies and all—from M to A. That threat is called Cross-Site Request Forgery; it is not mitigated by the Same Origin Policy and so additional measures must be provided to protect against it.
As an example, it prevents Farmville from checking the balance on your banking account. Or, even worse, messing with the form your are about to send (after entering the PIN/TAN) so they get all the money.
CORS is mainly a standard for web sites which are sure they do not need this kind of protection. It basically says "it's OK for a script from any web site to talk to me, no security can possibly be broken". So it really does allow things which would be forbidden by the SOP, on places where the protection is not needed and cross-domain web sites are beneficial. Think of meshups.