How to allow FontAwesome to load fonts from a different domain - css

When hosting FontAwesome on a CDN, how do you allow it to load fonts when that CDN's domain does not match your server's domain?
I have my media hosted in an S3 bucket, being served from a Cloudfront endpoint. My webpage, served from example.com, contains links to this Cloudfront endpoint, and all the initial media requests to this endpoint succeed. However, if I trigger any JS that tries to render new FontAwesome content, causing it to try and load fonts, I get an error like:
Access to Font at 'http://lkfejwifisj.cloudfront.net/font-awesome-4.2.0/fonts/fontawesome-webfont.d95d6f5d5ab7.woff?v=4.2.0' from origin 'http://example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.com' is therefore not allowed access.
I made my S3 bucket's CORS policy as open as possible with the configuration:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
However, that didn't fix the problem.
I'm using Chrome as my browser, and apparently this type of error has been mentioned many many times before. However, none of the proposed solutions are applicable, or don't work for me.
How do I fix this?
Why is Chrome saying "No 'Access-Control-Allow-Origin' header is present on the requested resource", when I explicitly allow all origins in my CORS configuration?

It turned out that my CORSConfiguration is correct, and actually fixes the problem, but my browser is caching the old request and so I still see the same error.
If I load the page in an Incognito browser, ensuring my cache is cleared, I don't get the error.

Related

Access websites with iFrame <X-Frame-Options>

I need to have https://web.whatsapp.com embedded in my website via iframe. I get the error of X-Frame-Options. I use express server and I tried to configure it with helmet:
app.use(
helmet.frameguard({
action: "sameorigin",
})
)
Doesn't seem to work. Same with deny. I read that ALLOW-FROM is not supported in Chrome browser anymore. Is there any chance to bypass or allow X-Frame-Options to accept certain origins? (Maybe there is any other options how to embed https://web.whatsapp.com to my website?).
X-Frame-Options prevents a site from being framed. As web.whatsapp.com prevents framing, there is nothing you can do to allow it being framed, unless you proxy the connection and remove headers. Adding headers to the site framing the other won't change anything.

"No 'Access-Control-Allow-Origin' header is present on the requested resource" on fonts urls. CloudFront with Lightsail Wordpress

I'm using cloudfront on lightsail on my website https://topshelfaquatics.com with the help of W3Total Cache. I've used all the possible ways like allowing headers (Origin) in Cloudfront but still it is not solving.
Can you suggest me a solution?
Please look at your network tab in the developer tools. This will give you information about the http calls. Most of the time the browser give this error when it's a xhr (ajax) call and no Access-Control-* headers has been set in the response. In order to solve this there are two possibilities:
Do not use xhr requests for fonts, so do not load fonts from JS. Use the default methods in html/css for loading fonts.
Add the required Access-Control-* headers to the http response. This requires involvement of cloudfont.net, so this solution might not be very realistic.
Cross-Origin Resource Sharing - CORS - is a mechanism that use some additional HTTP headers to inform the browser that access resource has different domain from origin.
You try access resource at Cloud Front, without setup the allowed domains int, below a example that enable CORS, for HTTP method GET and all headers, in Cloud Front:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>https://topshelfaquatics.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>1800</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served. ... Certain "cross-domain" requests, notably Ajax requests, are forbidden by default by the same-origin security policy.
Chrome browser install Extension:
https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf?hl=en

Blocked content in https

I have moved my Joomla website from one hoster to another and on the new hoster I get:
Blocked loading mixed active content "http://mywebsite.com/joomla/media/jui/css/bootstrap.css"
I understand the reason: I use https, and browser detects a http call.
But how do I fix this?
You change the source of your https website to point to the https version
If you can't, you can fix it for moden browsers with that http header:
Content-Security-Policy: upgrade-insecure-requests
See https://scotthelme.co.uk/migrating-from-http-to-https-ease-the-pain-with-csp-and-hsts/
Note: to improve security, you should use HSTS. It will redirect http to https directly in the browser, without insecure redirect.
Specifically about joomla:
Did you set
$live_site = 'https://www.your-domain.com';
in your configuration.php file ?
See https://www.joomlart.com/tutorials/joomla-tutorials/how-to-use-ssl-in-a-joomla-site

How to enable simple CORS on nginx

I installed Nginx on my laptop. My web server contains DASH streaming on-demand using the dash.js player which only hosted on localhost. I want to restrict only DASH dataset from localhost that can be used in that player. Can I use CORS for my purpose? I tried adding
location /{
add_header 'Access-Control-Allow-Origin' 'http://localhost';
}
but still any DASH dataset can still use the player which hosted on localhost. How to enable simple CORS features on Nginx? Is my understanding about CORS is wrong?
Thanks
I want to restrict only DASH dataset from localhost that can be used in that player. Can I use CORS for my purpose?
Not really. CORS is used for getting at resources cross-domain. If a player can natively play DASH (which none of the browsers do currently), then the content will play on any page, CORS support or not. The way DASH players work in-browser today is by loading the resources via XHR requests and sending the data with the media source extension API. To do this, the CORS headers are needed.
Cross-origin request blocking isn't really meant to prevent access to a resource. It's to prevent scripts on one page from accessing resources belonging to another page, effectively impersonating a user. Access-Control-Allow-Origin headers enable other pages to access those resources by effectively saying that the resource queried is safe for use.
If you want to actually block access to something, you should use allow/deny. http://nginx.org/en/docs/http/ngx_http_access_module.html

Google Cloud Storage fonts CORS issue

Static files in my app are uploaded to GCS and are set to public links.
when a static resource is requested (in this case a font) it hits a url like https://example.com/static/fonts/font.woff
the server then redirects the request to the apropriate GCS url to be served.
the problem here is that with chrome i get this CORS issue:
xxxxxxxxe3b8ccc0e3:1 Font from origin 'https://storage.googleapis.com' has been blocked from loading by Cross-Origin Resource Sharing policy: A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'https://example.com' is therefore not allowed access.
the CORS defaults on the bucket and all subfolders is set like so:
[{"origin": ["*"], "responseHeader": ["Content-Type"], "method": ["GET"], "maxAgeSeconds": 3600}]
the question is where is this credentials flag set?
i do redirect to the public link so its not an ajax request, the link is in the font-face declaration of the css file.
also it is not an option to set the origin to a specific domain or list of domains because my app is multitenant and there are multiple different domains accessing the same file.
this seems to work correctly when the request comes from http but gives this error when on https
also this works as expected in safari but does not with chrome.
Such issues, when hosting fonts on GCS, could also be related to missing CORS configuration on the GCS bucket.
(See https://cloud.google.com/storage/docs/cross-origin).
You may define cors access settings with:
gsutil cors set cors-config.json gs://my-bucket
And your cors-config.json could be, for example:
[
{
"origin": ["*"],
"responseHeader": ["Content-Type"],
"method": ["GET"],
"maxAgeSeconds": 3600
}
]
Meaning ok to read from all origins.
Edit from 2019: Chrome fixed this years ago!
Interesting! There is a Chrome bug (issue 544879) in which Chrome insists that it needs credentials for loading fonts, even though it does not. Looks like that's likely to be your problem.
While you wait for that bug to be fixed, you may consider these options:
Use HTTP instead of HTTPS when referencing storage.googleapis.com. HTTP may not be vulnerable to this problem.
List specific domains instead of a wildcard in yours CORS policy.
Rather than hosting a font and referencing it with #font-face, host a CSS file with the font encoded as a data URI. Example: https://www.filamentgroup.com/lab/font-loading.html
In our case, the issue was that we naively used the storage.cloud.google.com/path/to/resource public URL as the base Url for our front-end application, while it does not allow CORS request...😓
Instead, we had to use the storage.googleapis.com/path/to/resource one!
More information on our CORS is handled by google cloud

Resources