Refused to connect 'https://s3.console.aws.amazon.com/' in a frame because AWS is 'X-Frame-Options' to 'deny' - amazon-s3

I currently just use an AWS S3 Bucket to be able to show some of my HTML canvas animations, and never had issues until I created an iFrame for an ad platform that versions using a feed called Celtra.
I tried ?embed=true and target="_blank" mentioned in another question where the policy was SAMEDOMAIN, and not surprisingly neither worked.
Do I need to use a Create Object Lambda Access Point? According to Mozilla, DENY & SAMEORIGIN are the only option.
ALLOW-FROM uri
This is an obsolete directive that no longer works in modern browsers. Don't use it. In supporting legacy browsers, a page can be displayed in a frame only on the specified origin uri. Note that in the legacy Firefox implementation this still suffered from the same problem as SAMEORIGIN did — it doesn't check the frame ancestors to see if they are in the same origin. The Content-Security-Policy HTTP header has a frame-ancestors directive which you can use instead.

Yes, you have to use Lambda#Edge func to add custom HTTP response headers to AWS S3 bucket.
But judging by this topic, this one, and this doc, AWS does not add X-Frame-Options header on its own. Therefore your HTML canvas animations should not be blocked in the iframe.
If you wish to allow iframing at miltiple locations, the X-Frame-Options is not flexible enough. Use Conrent-Security-Policy (CSP) HTTP header with the frame-ancestors directive.
Conrent-Security-Policy: frame-ancestors *;
will allow iframing at any locations, while
Conrent-Security-Policy: frame-ancestors example.com friends.com;
allows to embed page have published this header only in example.com and friends.com sites only.
UPDATE
The HTTP header with white list of domains allowed to embed iframe:
`Conrent-Security-Policy: frame-ancestors example.com friends.com allowed_site.net`
must be published by your s3.console.aws.amazon.com/s3/buckets/advancedbanners page. This page should grant the permissions to embed itself.
I am not shure you can to publish CSP header on AWS S3 without Lambda#Edge func. You have to use exactly HTTP header, since frame-ancestors is not supported in the <meta http-equiv="Conrent-Security-Policy" content=" directives_here "> meta tag.
And you have to find a way to stop publishing the X-Frame-Options(XFO) header on AWS S3 because of Safari bug - XFO does not obsolete in favor CSP.

Related

How to set content-security-policy header?

The website https://www.example.com with header content-security-policy: frame-ancestors 'self'; is unable to open with <iframe>
This website contain a shareable url like https://www.example.com/#/shareablelink which should be allowed to open in <iframe> but as header content-security-policy: frame-ancestors 'self'; also applied to this page, it is not working as expected.
Is there any way do so?
Its frontend is build on angular 5+
HTTP headers publish on the backend (server), so only the site owner can change those.
Link (https://www.example.com/#/shareablelink) with hash # works tricky:
part before # is served by server - be sends to server on click and will get reply from server (if you do not handle onClick by script in browser)
part after # is served locally in browser (by script or by built-in browser navigation) and never be sent to server
Therefore CSP HTTP header on the page https://www.example.com/#/shareablelink always will be the same as on https://www.example.com/. The part #/shareablelink normally is a scroll to '/shareablelink' anchor, or could be handled by javascript for any purposes (even send XMLHttpRequest to server, get response and change the page's content but not the HTTP header)

S3 CORS policy for public bucket

It seems to be easy, but I don't know what I am missing.
I have a public bucket with a js script that I fetch from my web site. I noticed that I don't send Origin header to S3, it is not required and everything works without any CORS configurations.
What's more, even after I manually added Origin header to that GET call and explicitly disallowed GET and my domain via:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://www.nonexistingdomain.com</AllowedOrigin>
<AllowedMethod>POST</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
I can still get the content. What's going on here?
Ok, after a conversation with Quentin, I think I understand where I am misinterpreting how CORS should work.
In Java world, it's a very common practice to actually reject requests when Origin doesn't match. Here is another thread where it's mentioned.
If we take Spring as an example(which is de-facto standard in Java world), here is what happens when CORS filter is added:
String allowOrigin = checkOrigin(config, requestOrigin);
...
if (allowOrigin == null) {
logger.debug("Reject: '" + requestOrigin + "' origin is not allowed");
rejectRequest(response);
return false;
}
where:
/**
* Invoked when one of the CORS checks failed.
*/
protected void rejectRequest(ServerHttpResponse response) {
response.setStatusCode(HttpStatus.FORBIDDEN);
}
You can find the code here.
But to my surprise, it is not such a common practice with other stacks and server-side technologies. Another common approach would be to send whatever CORS configuration they have to the browser and leave the decision to it.
S3 is even more tricky: it only sends CORS response headers when the bucket CORS rules match the CORS-enabled request(a request qith Origin header). Otherwise, there would be no CORS response headers.
The Same Origin Policy is a feature enforced by browsers which prevents JavaScript running on one website from reading data from a different website. (This stops random websites using JavaScript to use your browser to skip past your corporate firewall and access your intranet or read your GMail with your cookies).
CORS lets a website relax the Same Origin Policy to allow other websites to read data from it that way.
CORS is not authentication/authorisation. Your public bucket is public.
You aren't using JavaScript to read data from your bucket, you are loading the JS directly from the bucket.
Let's break down the problem and try to understand the fundamentals of CORS.
What is Cross-Origin Request & CORS?
Cross-Origin Request: A request for a resource (like
an image or a font) outside of the origin is known as a cross-origin
request.
CORS is helpful when you are requesting for a protected resource from another origin.
Cross-Origin Request Sharing: A request for a protected resource (like an image or a font or an XHR request) outside of the origin is known as a cross-origin request.
Why do we need CORS when the resources can be protected by using authentication/authorization tokens?
CORS is the first line of defense. When both the client (e.g., browsers) and servers are CORS-aware, clients will allow only requests from the specific origins to the servers as per instructed by the servers.
By default, browsers are supposed to implement same-origin policy security mechanism as per the guidelines on building the browser. Almost all the modern browser implement same-origin policy that instructs the browsers to allow requests to the servers if the origin is the same.
Same-origin policy is a security mechanism of a browser, you can read more about it here. It is because of this feature of browsers, the browser blocks all the request when the designation origin and the source origin are different. (Servers are not even aware that this is happening, Wow!)
For simpler use cases, when the assets(js, CSS, images, fonts), XHR resources are accessible with the same origin, there is no need to worry about CORS.
If assets are hosted on another origin or XHR resource are hosted on servers with a different domain that the source then browsers will not deny the request to cross-origin by default. Only with appropriate CORS request and response headers, browsers are allowed to make cross-origin requests.
Let's look at the request and response headers.
Request headers
Origin
Access-Control-Request-Method
Access-Control-Request-Headers
Response headers
Access-Control-Allow-Origin
Access-Control-Allow-Credentials
Access-Control-Expose-Headers
Access-Control-Max-Age
Access-Control-Allow-Methods Access-Control-Allow-Headers
For setting up CORS the Origin, and Access-Control-Allow-Origin headers are needed. Browsers will automatically add Origin header to every request, so a developer needs to configure only Access-Control-Allow-Origin response header.
For protecting access to resources only from specific domains, S3 provides an option to configure CORS rules. If the value of Access-Control-Allow-Origin header is * all the cross-origin requests are allowed, or else define a comma-separated list of domains.
There are a couple of things you need to be aware of when using CORS.
It's the first level of defense to a protected resource and not the ultimate defense.
You still need to implement appropriate authentication & authorization for the resource to perform CRUD operations on the server.
Implementing Same Origin Policy is a guideline for building the browser and are not mandatory.
CORS headers are useful only when clients accept the headers. Only modern browsers accept CORS headers. If you are not using browsers to make the resource request, then CROS do not apply.
If you type the link in the address bar of the browser, the CORS rules are not applied to because the browser does not send the Origin header to the server. The Origin header is sent by the browser only on the subsequent resource request (stylesheets, js files, fonts) and XHR requests by the origin.
If you access the resource file by directly typing the link in the address bar, the browser does not send Origin header to that request.
Also, if you want to restrict GET access use S3 pre-signed URL on a private bucket.

How to enable CORS for Catalyst

Having a Perl Catalyst application, which produces JSON, I need to read that JSON content using jQuery within an HTML page, served by an Apache server. Both applications, Catalyst and Apache are running on the same host.
When I access the Catalyst URL from Apache I get the error
Access to XMLHttpRequest at 'http://localhost:3000/abc/json_list' from origin 'http://localhost:8888' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
As I red in many topics, a header (or more) must be set. In this case the Catalyst must be set but I don't know how.
Any hint?
Catalyst allows you to set response headers using the header method on the response object.
$c->res->header( "Access-Control-Allow-Origin" => "http://localhost:8888" );
Consider using a controller's sub auto or using existing middleware if you have multiple endpoints that need to provide permission via CORS.

Referrer and origin preflight request headers in Safari are not changing when user navigates

I have two web pages hosted on a.example.com and b.example. Each web page is including a script with a <script> tag, hosted on another domain and served with correct CORS headers.
At a certain point, user navigates from a.example.com to b.example.com.
Safari has here a strange behavior: the referrer and origin headers in preflight request are filled with a.example.com, making the server sending a bad value in Access-Control-Allow-Origin (and so the script can't be executed).
Is there a way to force Safari browser to send correct origin header in that kind of scenario ?
Does the cache policy for the script include Vary: Origin?
Respectively is there actually a second request after navigating to b.example.com?
If not, there is a chance that Safari is actually serving the script from cache - despite the Access-Control-Allow-Origin policy forbidding it to access the resource. Which is a conforming behavior, if the cache policy isn't configured correctly.
It seemed to be indeed a Safari bug.
The issue is not reproductible on Safari 10.0. It repro only on Safari 9.1.1 / 9.1.3.

Enable mixed content loading in latest Chrome and firefox with http headers

I have a website that has to be served under HTTPS
However, there is a section of the site that displays BBC news stories within an iframe which is in a popup window. Here the content is not shown as both browsers say the BBC content is insecure (i.e.mixed content).
I have tried setting the header Content-Security-Policy:
to
"default-src 'self' *.my_domian.net http://*.my_domian.net http://*.bbc.co.uk *.fonts.com 'unsafe-inline' 'unsafe-eval';"
Which has an effect on other content so it is working. I have also checked the headers are sent.
However, both Chrome and Firefox continue to tell me the BBC content is insecure and it isn't shown in the iframe.
Is it possible to allow content from bbc.co.uk on a secure site ?
Have I miss understood the purpose of Content-Security-Policy ?
I have also tried frame-src in the header with no luck.
Thanks
CSP level 2 is already being applied in Chrome, and level 2 has additional frame handling.
see here: https://www.w3.org/TR/CSP2/#directive-frame-ancestors
and here: https://www.w3.org/TR/CSP2/#directive-frame-src
frame-src is being deprecated, user frame-ancestors