CloudFront Origin Basic Authorization - amazon-cloudfront

My origin server is password-protected. I need CloudFront to authenticate with it and cache the contents of my site.
This is basic authorization. I've set the Authorization header by going into Origin settings and setting the Header at the bottom of the page:
Header Name Value
Authorization Basic myusername:mypassword
My problem is that my CloudFront url is prompting me for a username and password. Maybe it's caching .htaccess. How can I prevent it from doing this?

Your configuration seems valid.
Custom origin headers are sent to the origin in the request. If the same header is already present in the request, it is automatically removed, first, then the custom header is added. The viewer doesn't see it.

Most likely you have to base64 encode your myusername:mypassword pair, so it looks like:
Header Name Value
Authorization Basic base64encode(username:password)
Make sure you invalidate cache before running any tries

Related

Why are my cross site cookies not working?

I have been working on a uni project and I'm getting really stuck on why the cross site authentication cookie from our backend isn't set when I do a CORS request to it from our backend.
Our setup is as follows:
A frontend on https://frontend-domain.com sends a CORS request to https://backend-domain.com with credentials in the post body, expecting a Set-Cookie: auth-token header in the response, if credentials are correct.
The fetch to the backend has credentials: 'include' set.
The backend response includes Access-Control-Allow-Credentials: true and explicitly states Access-Control-Allow-Origin: https://frontend-domain.com. The Allowed Methods header is also correct.
The token cookie in the Set-Cookie header has the attributes SameSite=Noneand Secure, it's domain attribute is Domain=backend-domain.com.
As far as I could find on the mozilla docs or here on stack overflow, these are all the requirements for cross site cookies to work. I expected the Set-Cookie header would make the browser set the cookie, which would then be sent along with all further requests to https://backend-domain.com, given credentials: 'include' is set.
However, the cookie is never set.
Can anyone help me? I am absolutely clueless by now.
Thank you very much for reading and helping!
Edit
I am using Firefox right now.
Here is a screenshot of the request:
And here is the response:
All of the Set-Cookie headers you can see in the response dont result in an actual cookie.
The SameSite attribute of a cookie controls whether this cookie is included in
subrequests (such as the ones made by an <img> or <iframe> element or a Javascript fetch command) to a different origin
top-level navigation requests (which load a new page into the current or a new browser tab).
Details are given here. Note especially the subtly different treatment of navigation with GET and POST ("Lax-Allowing-Unsafe").
Cookies in subrequests (but not top-level navigation requests) may be additionally restricted based on browser settings if they are third-party cookies, that is, if the top-level domains of their origin and the sending web page differ. In other words: Cookies from backend-domain.com count as third-party cookies when a request is made by an HTML page from frontend-domain.com, and this is what caused the issue in your case.

Is it possible to only allow CORS from one website only and not directly?

Suppose I have a web application at origin.com. When I browse origin.com it request cross-site data from datafeed.origin.com. I have following written in .htaccess of datafeed.origin.com Header set Access-Control-Allow-Origin origin.com. Everything works perfectly till this point.
What I need is protect datafeed.origin.com. How can I prevent this domain from browsing directly from browser or any other application. Only allow access when cross referencing from origin.com.
You can specify the origin when setting the Access-Control-Allow-Origin header:
Access-Control-Allow-Origin: <origin>[, <origin>]*
Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
Looking at your post it looks like you've done this, so cross origin requests should fail from other domains

access gitlab files through ajax request

I would like to access the raw files in a repository of mine that is on gitlab through an ajax request. However, it's not working, I'm wondering if I have to setup my project accordingly or something. Obviously my project is public. This is the error message I get :
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Which means it's on their end.
To understand Access-Control-Allow-Origin header, I highly recommend How does Access-Control-Allow-Origin header work?
When Site A tries to fetch content from Site B, Site B can send an
Access-Control-Allow-Origin response header to tell the browser that
the content of this page is accessible to certain origins. (An origin
is a domain, plus a scheme and port number.) By default, Site B's
pages are not accessible to any other origin; using the
Access-Control-Allow-Origin header opens a door for cross-origin
access by specific requesting origins.
If your GitLab is hosted on gitlab.com, I don't see a way to add your domain to response header.
The easiest solution is wrapping XMLHttpRequests to GitLab in requests to your application - and on the backend you will simply fetch and return data. For example, you won't send a XML request to https://gitlab.com/pdaw/test/raw/master/README.md, but tohttps://my.app.com/fetch-file?file=pdaw/test/raw/master/README.md. On the backend of the fetch-file action you will fetch and return raw data from https://gitlab.com/pdaw/test/raw/master/README.md

Amazon Cloudfront removes Referer header

I am using Amazon CloudFront to deliver some HDS files. I have an origin server which check the HTTP HEADER REFERER and in case is no allowed it block it.
The problem is that cloud front is removing the referer header, so it is not forwarded to the origin.
Is it possible to tell Amazon not to do it?
Within days of writing the answer below, changes have been announced to Cloudfront. Cloudfront will now pass through headers you select and can add some headers of its own.
However, much of what I stated below remains true. Note that in the announcement, an option is offered to forward all headers which, as I suggested, would effectively disable caching. There's also an option to forward specific headers, which will cause Cloudfront to cache the object against the complete set of forwarded headers -- not just the uri -- meaning that the effectiveness of the cache is somewhat reduced, since Cloudfront has no option but to assume that the inclusion of the header might modify the response the server will generate for that request.
Each of your CloudFront distributions now contains a list of headers that are to be forwarded to the origin server. You have three options:
None - This option requests the original behavior.
All - This option forwards all headers and effectively disables all caching at the edge.
Whitelist - This option give you full control of the headers that are to be forwarded. The list starts out empty, and grows as you add more headers. You can add common HTTP headers by choosing them from a list. You can also add "custom" headers by simply entering the name.
If you choose the Whitelist option, each header that you add to the list becomes part of the cache key for the URLs associated with the distribution. Adding a header to the list simply tells CloudFront that the value of the header can affect the content returned by the origin server.
http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/
Cloudfront does remove the Referer header along with several others that are not particularly meaningful -- or whose presence would cause illogical consequences -- in the world of cached content.
http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html
Just like cookies, if the Referer: header were allowed to remain, such that the origin could see it and react to it, that would imply that the object should be cached based on the request plus the referring page, which would seem to largely defeat the cachability of objects. Otherwise, if the origin did react to an undesired referer and send no-cache responses, that would be all well and good until the first legitimate request came in, the response to which would be served to subsequent requesters regardless of their referer, also largely defeating the purpose.
RFC-2616 Section 13 requires that a cache return a response that has been "checked for equivalence with what the origin server would have returned," and this implies that the response be valid based on all headers in the request.
The same thing goes for User-agent and other headers an origin server might use to modify its response... if you need to react to these values at the origin, there's little obvious purpose for serving them with a CDN.
Referring page-based tests are quite a primitive measure, the way many people use them, since headers are so trivial to forge.
If you are dealing with a platform that you don't control, and this is something you need to override (with a dummy value, just to keep the existing system "happy,") then a reverse proxy in front of the origin server could serve such a purpose, with Cloudfront using the reverse proxy as its origin.
In today's newsletter amazon announced that it is now possible to forward request headers with cloudfront. See: http://aws.amazon.com/de/about-aws/whats-new/2014/06/26/amazon-cloudfront-device-detection-geo-targeting-host-header-cors/

Is access-control-origin: * safe if session based auth is disallowed? [duplicate]

I recently had to set Access-Control-Allow-Origin to * in order to be able to make cross-subdomain AJAX calls. I feel like this might be a security problem. What risks am I exposing myself to if I keep the setting?
By responding with Access-Control-Allow-Origin: *, the requested resource allows sharing with every origin. This basically means that any site can send an XHR request to your site and access the server’s response which would not be the case if you hadn’t implemented this CORS response.
So any site can make a request to your site on behalf of their visitors and process its response. If you have something implemented like an authentication or authorization scheme that is based on something that is automatically provided by the browser (cookies, cookie-based sessions, etc.), the requests triggered by the third party sites will use them too.
This indeed poses a security risk, particularly if you allow resource sharing not just for selected resources but for every resource. In this context you should have a look at When is it safe to enable CORS?.
Update (2020-10-07)
Current Fetch Standard omits the credentials when credentials mode is set to include, if Access-Control-Allow-Origin is set to *.
Therefore, if you are using a cookie-based authentication, your credentials will not be sent on the request.
Access-Control-Allow-Origin: * is totally safe to add to any resource, unless that resource contains private data protected by something other than standard credentials. Standard credentials are cookies, HTTP basic auth, and TLS client certificates.
Eg: Data protected by cookies is safe
Imagine https://example.com/users-private-data, which may expose private data depending on the user's logged in state. This state uses a session cookie. It's safe to add Access-Control-Allow-Origin: * to this resource, as this header only allows access to the response if the request is made without cookies, and cookies are required to get the private data. As a result, no private data is leaked.
Eg: Data protected by location / ip / internal network is not safe (unfortunately common with intranets and home appliances):
Imagine https://intranet.example.com/company-private-data, which exposes private company data, but this can only be accessed if you're on the company's wifi network. It's not safe to add Access-Control-Allow-Origin: * to this resource, as it's protected using something other than standard credentials. Otherwise, a bad script could use you as a tunnel to the intranet.
Rule of thumb
Imagine what a user would see if they accessed the resource in an incognito window. If you're happy with everyone seeing this content (including the source code the browser received), it's safe to add Access-Control-Allow-Origin: *.
AFAIK, Access-Control-Allow-Origin is just a http header sent from the server to the browser. Limiting it to a specific address (or disabling it) does not make your site safer for, for example, robots. If robots want to, they can just ignore the header. The regular browsers out there (Explorer, Chrome, etc.) by default honor the header. But an application like Postman simply ignores it.
The server end doesn't actually check what the 'origin' is of the request when it returns the response. It just adds the http header. It's the browser (the client end) which sent the request that decides to read the access-control header and act upon it. Note that in the case of XHR it may use a special 'OPTIONS' request to ask for the headers first.
So, anyone with creative scripting abilities can easily ignore the whole header, whatever is set in it.
See also Possible security issues of setting Access-Control-Allow-Origin.
Now to actually answer the question
I can't help but feel that I'm putting my environment to security
risks.
If anyone wants to attack you, they can easily bypass the Access-Control-Allow-Origin. But by enabling '*' you do give the attacker a few more 'attack vectors' to play with, like, using regular webbrowsers that honor that HTTP header.
Here are 2 examples posted as comments, when a wildcard is really problematic:
Suppose I log into my bank's website. If I go to another page and then
go back to my bank, I'm still logged in because of a cookie. Other
users on the internet can hit the same URLs at my bank as I do, yet
they won't be able to access my account without the cookie. If
cross-origin requests are allowed, a malicious website can effectively
impersonate the user.
– Brad
Suppose you have a common home router, such as a Linksys WRT54g or
something. Suppose that router allows cross-origin requests. A script
on my web page could make HTTP requests to common router IP addresses
(like 192.168.1.1) and reconfigure your router to allow attacks. It
can even use your router directly as a DDoS node. (Most routers have
test pages which allow for pings or simple HTTP server checks. These
can be abused en masse.)
– Brad
I feel that these comments should have been answers, because they explain the problem with a real life example.
This answer was originally written as a reply to What are the security implications of setting Access-Control-Allow-Headers: *, if any? and was merged despite being irrelevant to this question.
To set it to a wildcard *, means to allow all headers apart from safelisted ones, and remove restrictions that keeps them safe.
These are the restrictions for the 4 safelisted headers to be considered safe:
For Accept-Language and Content-Language: can only have values consisting of 0-9, A-Z, a-z, space or *,-.;=.
For Accept and Content-Type: can't contain a CORS-unsafe request header byte: 0x00-0x1F (except for 0x09 (HT), which is allowed), "():<>?#[\]{}, and 0x7F (DEL).
For Content-Type: needs to have a MIME type of its parsed value (ignoring parameters) of either application/x-www-form-urlencoded, multipart/form-data, or text/plain.
For any header: the value’s length can't be greater than 128.
For simplicity's sake, I'll base my answer on these headers.
Depending on server implementation, simply removing these limitations can be very dangerous (to the user).
For example, this outdated wordpress plugin has a reflected XSS vulnerability where the value of Accept-Language was parsed and rendered on the page as-is, causing script execution on the user's browser should a malicious payload be included in the value.
With the wildcard header Access-Control-Allow-Headers: *, a third party site redirecting to your site could set the value of the header to Accept Language: <script src="https://example.com/malicious-script.js"></script>, given that the wildcard removes the restriction in Point 1 above.
The preflight response would then give the greenlight to this request, and the user will be redirected to your site, triggering an XSS on their browser, which impact can range from an annoying popup to losing control of their account through cookie hijacking.
Thus, I would strongly recommend against setting a wildcard unless it is for an API endpoint where nothing is being rendered on the page.
You can set Access-Control-Allow-Headers: Pragma as an alternative solution to your problem.
Note that the value * only counts as a special wildcard value for requests without credentials (requests without HTTP cookies or HTTP authentication information), otherwise it will be read as a literal header. Documentation
In scenario where server attempts to disable the CORS completely by setting below headers.
Access-Control-Allow-Origin: * (tells the browser that server accepts
cross site requests from any ORIGIN)
Access-Control-Allow-Credentials: true (tells the browser that cross
site requests can send cookies)
There is a fail safe implemented in browsers that will result in below error
"Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’"
So in most scenarios setting ‘Access-Control-Allow-Origin’ to * will not be a problem. However to secure against attacks, the server can maintain a list of allowed origins and whenever server gets a cross origin request, it can validate the ORIGIN header against the list of allowed origins and then echo back the same in Access-Control-Allow-Origin header.
Since ORIGIN header can't be changed by javascript running on the browser, the malicious site will not be able to spoof it.

Resources