Google Cloud Storage fonts CORS issue - css

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

Related

"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

How to ensure my CDN caches CORS requests by origin?

I currently use Akamai as a CDN for my app, which is served over multiple subdomains.
I recently realized that Akamai is caching CORS requests the same, regardless of the origin from which they were requested.
This of course causes clients that make requests with a different Origin than the cached response to fail (since they have a different response header for Access-Control-Allow-Origin than they should)
Many suggest supplying the Vary: Origin request header to avoid this issue, but according to Akamai's docs and this Akamai community post, this isn't supported by Akamai.
How can I force Akamai to cache things uniquely by Origin if an Origin header is present in the request?
I did some research, and it appears this can be done by adding a new Rule in your Akamai config, like so:
Note that if you do this - REMEMBER - this changes your cache key at Akamai, so anything that was cached before is essentially NOT CACHED anymore! Also, as noted in the yellow warning labels, this can make it harder to force reset your cache using Akamai's url purging tools. You could remove the If block, and just include Origin header as a similar Cache ID Modification rule too, if you were ok with changing the cache key for all your content that this rule would apply to.
So in short, try this out on a small section of your site first!
More details can be found in this related post on Stack Overflow
We have hosted an API on Akamai. I had similar requirement, but we wanted to use the cached response on Akamai for all the touchpoints. But without CORS settings, it used to cache the response from first origin, and then keep it in cache, and the following requests from other touch points use to fail due to cached origin header.
We solved the problem with using API Gateway feature provided by Akamai. You can find it under API Definition. Custom cache parameters can also be defined here. Please see the screen shot for the CORS settings. Now it cached the response from backend and serve to the requester as per the allowed origin list.
CORS Setting in API Definition

How to allow FontAwesome to load fonts from a different domain

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.

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

how to use CORS mechanism in native client

For example,I hava a pnacl myapp.pexe , And my website is www.A.com. and myapp.pexe and www.A.com are on the same server. However, the website www.B.com need to access the myapp.pexe. And i got a error, Native Client: access to manifest url was denied.
Using CORS can slove this problem? If using CORS can slove this problem, how to do ?
This answer is not Native Client specific. Accessing Native Client resources from another origin uses the standard CORS mechanism.
To answer your question, though:
This can be done by setting up the correct CORS response headers on the A.com server. There are many online resources that can describe how to do this: take a look at http://www.html5rocks.com/en/tutorials/cors/ for example.
For the simplest case, the solution is to return one additional header in the GET response for myapp.pexe and myapp.nmf:
Access-Control-Allow-Origin: http://A.com
There are more headers that are required for other request method types, content types, sending credentials, etc.

Resources