Cross Domain CORS and Images - html

I'm using AWS S3 and Cloudfront to deliver images to my sites/domains.
I've been looking at AWS S3 CORS and I wanted to ask if I limit the domains will this restrict other domains from access my images.
If I was to set the following on a Bucket that contained images would this stop other domains from access the images within the bucket or do images operate differently to under resources under CORS.
<AllowedOrigin>http://www.example.com</AllowedOrigin>
Essentially I would like to restrict my images to my sites only.
Also I heard you must include the Cloudfront as another AllowedOrigin for this work - Can someone confirm this?
thanks

CORS is a policy enforced by a browser. Its not going to prevent users from downloading images from your cloudfront distribution.
You have two options.
Make all your files private and provide access via signed urls. Cloudfront wont really cache images in this case however.
The other option is to configure cloudfront to forward all headers, and use a bucket policy to limit access based on referrers. You can get around this, but it would prevent most casual hotlinking.

Related

How do I download files from my Django website?

I have a small django website that allows file uploading hosted on pythonanywhere. The files are uploaded to aws s3.
Now the problem is that even with the presence of download attribute in the html, the browser still renders the file instead of downloading it
<a download href="{{file_url}}">Download</a>
From Mozilla Developer Network Anchor element reference:
"....download only works for same-origin URLs, or the blob: and data: schemes..."
Your aws s3 links most probably are not same-origin (same domain etc) as your site.
If that is what you are running into, one work around that comes to my mind is, you can make on your site a transfer url that receives the document identifier, downloads from aws s3, and then forwards its content as response. This way you can also control content-type like headers that you may need to explicitly set to make the browser behave the way you want.
One addition, if you decide to have a solution like that, you have to take precautions to control the request content that transfer url, and only transfer content that your web site intended to. Otherwise you will have opened a vulnerability similar to what is called an "Open Redirect" vulnerability.

AWS CloudFront SDK - testing if a file can be served

I have a server app that can serve files from it's local file system. However before it does that it should check to see whether the file could instead be served from CloudFront and, if so, redirect there instead.
Not all the files on the server are not necessarily duplicated in the S3 bucket origin(s) associated with the CloudFront distribution, so there will be some cases where a redirect to CloudFront is inappropriate.
How can I query the CloudFront SDK to find out whether a redirect to that would be successful (and not return a 404 for example)?
I appreciate that I could query the contents of an associated S3 bucket origin instead, but ideally I'd like to get the result from CloudFront so that it can do all of it's caching and failover between multiple origins and origin groups and I don't really want to have to replicate all of that logic in my code!
I happen to be using the c# SDK, but happy to accept answers in any language, it's more the principals behind it that I'm interested in. Am I perhaps thinking about this in the wrong way?
I was vastly overthinking this. Just making a http request with HEAD rather than GET and checking the response was 200 was all that was needed.

HTML: Load image only once for multiple calls

I am working on a Laravel application which is based on a social network. Images are stored on S3 bucket where pricing is based on the number of GET/PUT/DELETE.... requests. I want to reduced the number of request sent to the S3 buckets in any way.
Scenario: Imagine a facebook post and comments
A user's profile picture is being pulled from S3 bucket on a page load. In the comments section of a post a user has commented 10 times. I write a code as usual
<img src="https://s3-ap-southeast-1.amazonaws.com/somebucket/32431435696950423.jpg">
for each comment a new request is sent to the bucket? or by default the image is cached after the first request and pulled from the cache for the rest?
How do I achieve avoiding a multiple GET request for a single image?
It depends on browser implementation and your image Cache-Control header. Most of modern browsers support caching. They will cache your image if your image is allowed to be cached, and vice-versa. Check When multiple instances of same images are embedded in an HTML, does that load the image once? question.
AWS S3 can be configured to allow your objects being cached (read how to add cache control in AWS S3).
But, if your site has a high traffic, I suggest you to use AWS CloudFront instead of pure S3. It is a CDN (Content Delivery Network). It is faster and can be cheaper than normal S3.
"or by default the image is cached after the first request and pulled from the cache for the rest?" It is the correct answer only if image has the same source and the file name.
So 10 the same images from one URL will be downloaded once.

A good practice to set my custom domains on Heroku

Basically, Heroku gives you a domain named by default: XXX.herokuapp.com.
On my own, I have a set of REST apis that I would like to set on a domain named: api.myDomain.com.
On the same time, I have my HTML files (web view) distributed by the same server as the REST API.
It's similar to this; embedding static files on server in a dist folder.
I expect the domain serving those HTML/JS files to be www.myDomain.com.
I thought about putting them clearly on a distinct server dedicated to static files, but the fact is that Single Page Application should be controlled by a server, in order to make the refresh works (F5 redirecting to index.html), that's why I chose to use the same server as REST apis.
An alternative would be to dedicate ANOTHER server to treat only static files, independent of the REST Apis' server.
How to deal with both domains (api and www) while sources being on the same servers?
Or should I completely rethink the strategy?
You can just set both domains to direct to your page by setting it up in your app settings, but then I'm pretty sure that would mean api.myDomain.com/dist would show your static things, and www.myDomain.com could show your api things.
https://devcenter.heroku.com/articles/custom-domains
Another way you could do this might be by doing some things with your actual code, but we don't really know what your code is like right now.

Request permission to perform Cross-Origin XMLHttpRequest

I am working on a project where I need make cross-origin requests, but there does not appear to be any way to allow this in a pure web page.
Chrome extensions can simply request permission to the domains they would like to make requests to as in the following example.
"permissions": [
"http://www.google.com/",
"https://www.google.com/"
]
http://developer.chrome.com/extensions/xhr.html
I found https://developers.google.com/chrome/apps/docs/no_crx which seemed like something closer to what I was looking for, but the only permissions allowed are "geolocation", "notifications", and "unlimitedStorage".
There is the HTTP header Access-Control-Allow-Origin which could be set on the domains I would like to make requests to, but they are not under my control so that is not practical.
Similarly the Content-Security-Policy: connect-src https://www.google.com; is primarily used to further restrict access instead of opening up access.
http://www.html5rocks.com/en/tutorials/security/content-security-policy/
I understand the security concerns, but as a quick search will show people get around this by making a proxy server. Wouldn't it make sense to allow the equivalent request to be made, meaning a request without the user's session/cookie information (like incognito mode)? Or some mechanism by which the page can request permission in the same manner as an extension? Seems somewhat backwards to require things like this to be down in browser specific manner.
Just like webspeech api (or getUserMedia) requests access to use microphone.
Any thoughts or perhaps something I missed?
EDIT: I posted this elsewhere and got:
If you are making requests from domains that are under your control, there are other options (like JSONP) that you can use to access data from another domain. Or, you can load an iframe and use postMessage() to interact with the contents - there are lots of tools that also enforce that the domain you're trying to communicate with is willing to share that data.
Me:
JSONP looks like a solution for data sources that provide JSON, but I am not sure that will solve my overall problem. I am trying to create a tool that will pull in data from a variety of sources to do both displaying a result and interpreting the information to perform an action. One query might be a google search which jsonp or the other official methods should allow for, but that does not work for scraping data from other web pages. All of the requests being made will not require user session information and thus a proxy would work, but will add latency and maintenance costs.
The postMessage() interface would require the pages being requested to implement listeners right?
So far the "best" solution still seems to be to have a companion extension that runs in a privileged environment that can make the requests and communicate the results with the page. The tool does a variety of other things that work within a web page so I would rather leave the primary environment as the web page with the option to run the extension.