AWS CloudFront: Font from origin has been blocked from loading by Cross-Origin Resource Sharing policy
Asked Answered
N

15

176

I'm receiving the following error on a couple of Chrome browsers but not all. Not sure entirely what the issue is at this point.

Font from origin https://ABCDEFG.cloudfront.net has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin https://sub.domain.example is therefore not allowed access.

I have the following CORS Configuration on S3

<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedHeader>*</AllowedHeader>
   <AllowedMethod>GET</AllowedMethod>
 </CORSRule>
</CORSConfiguration>

The request

Remote Address:1.2.3.4:443
Request URL:https://abcdefg.cloudfront.net/folder/path/icons-f10eba064933db447695cf85b06f7df3.woff
Request Method:GET
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Encoding:gzip,deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Host:abcdefg.cloudfront.net
Origin:https://sub.domain.example
Pragma:no-cache
Referer:https://abcdefg.cloudfront.net/folder/path/icons-e283e9c896b17f5fb5717f7c9f6b05eb.css
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36

All other requests from Cloudfront/S3 work properly, including JS files.

Nurmi answered 30/8, 2014 at 0:50 Comment(7)
I'm having the same problem... I started noticing it after upgrading to chrome 37.0.2062.94Carolinacaroline
After updating the CORS Configuration, I renamed the assets and managed to get it working. So either 1) The CORS Configuration is applied on file creation only (not update) OR 2) the CORS Configuration is cached at Cloudfront. I will post this as an answer if others can confirm it works for them too.Nurmi
Just noticed this with Chrome v. 37.0.2062.94 but not an earlier version. I don't have a CORS configuration at all on S3, so this shouldn't be happening, right?Geometrize
Got this problem now - what are your recommendations for a fix?Prizefight
@Geometrize you need the right CORS config. Test in firefox and that will give you the (probably) the same result.Distressful
@RichPeck - fix by adding the correct CORS config to S3 (or if automatically creating your CDN from source, then it's a bit more complicated -- you have to add the appropriate headers, then invalidate your cached fonts)... #12230344 see answer below for more detailsDistressful
It's 2015 and I just got this problem.Oud
R
99

Add this rule to your .htaccess

Header add Access-Control-Allow-Origin "*"

even better, as suggested by @david thomas, you can use a specific domain value, e.g.

Header add Access-Control-Allow-Origin "your-domain.example"
Randle answered 30/1, 2015 at 13:27 Comment(5)
Hi, what's the difference with Header set Access-Control-Allow-Origin "*" ? ThanksStamford
for windows people, set <add name="Access-Control-Allow-Origin" value="*" /> under <customHeaders> in web.config file. Have a nice dayPullen
@Simone the difference is that with "add" the response header is added to the existing set of headers, even if this header already exists. This can result in two (or more) headers having the same name; whereas with "set" the response header is set, replacing any previous header with this name. In this case is the same cause * includes them all.Randle
Just noting Access-Control-Allow-Origin "*" is potentially insecure as it opens the domain to javascript access from any domain. You should use a specific domain value instead, e.g Access-Control-Allow-Origin "http://example1.com" See also https://mcmap.net/q/17829/-how-does-the-39-access-control-allow-origin-39-header-work for a good explanation.Debate
YOU ARE MY LIFE SAVER !Jarvey
D
60

Chrome since ~Sep/Oct 2014 makes fonts subject to the same CORS checks as Firefox has done https://code.google.com/p/chromium/issues/detail?id=286681. There is a discussion on this in https://groups.google.com/a/chromium.org/forum/?fromgroups=#!topic/blink-dev/TT9D5-Zfnzw

Given that for fonts the browser may do a preflight check, then your S3 policy needs the cors request header as well. You can check your page in say Safari (which at present doesn't do CORS checking for fonts) and Firefox (that does) to double check this is the problem described.

See Stack overflow answer on Amazon S3 CORS (Cross-Origin Resource Sharing) and Firefox cross-domain font loading for the Amazon S3 CORS details.

NB in general because this used to apply to Firefox only, so it may help to search for Firefox rather than Chrome.

Distressful answered 6/9, 2014 at 7:48 Comment(5)
Thanks for this answer, looks like it may be a problem for many others. Although my problem was occurring in a stable build of Chrome.Nurmi
This is happening in Chrome now.Beak
As people keep referring (including myself!) to this answer, I've made it less historical and more relevant to present day.Distressful
Also FYI I discovered that a error message "has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin" was actually to do with having a bad path to a font file in my original server, and cloudfront then redirecting to the homepage of my server (and either the redirect response or the homepage didn't have the CORS headers). Confusing, but solved by using the correct path to the actual font file (not a CORS issue, strictly speaking).Distressful
Hey @DallasClark, you may want to choose an accepted answer for your question. Thanks Tim, your links and explanations were helpful in my experience. Cheers.Petiolule
L
48

I was able to solve the problem by simply adding <AllowedMethod>HEAD</AllowedMethod> to the CORS policy of the S3 Bucket.

Example:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Lona answered 29/12, 2016 at 22:14 Comment(3)
not sure about security though, would be nice if someone had some input on that..Mcentire
Doe this change need time to propagate? I just added <AllowedMethod>HEAD</AllowedMethod> to my CORS policy on the bucket and it's still not working.Hannahannah
usually no, it should take max. couple minutesMcentire
H
31

Nginx:

location ~* \.(eot|ttf|woff)$ {
   add_header Access-Control-Allow-Origin '*';
}

AWS S3:

  1. Select your bucket
  2. Click properties on the right top
  3. Permisions => Edit Cors Configuration => Save
  4. Save

http://schock.net/articles/2013/07/03/hosting-web-fonts-on-a-cdn-youre-going-to-need-some-cors/

Hellenhellene answered 4/7, 2015 at 0:12 Comment(1)
after adding this, get 404 not found.Arnitaarno
R
13

On June 26, 2014 AWS released proper Vary: Origin behavior on CloudFront so now you just

Set a CORS Configuration for your S3 bucket:

<AllowedOrigin>*</AllowedOrigin>

In CloudFront -> Distribution -> Behaviors for this origin, use the Forward Headers: Whitelist option and whitelist the 'Origin' header.

Wait for ~20 minutes while CloudFront propagates the new rule

Now your CloudFront distribution should cache different responses (with proper CORS headers) for different client Origin headers.

Ruggiero answered 17/3, 2015 at 6:3 Comment(1)
This doesn't seem to work, do you have more details? I enabled this but I still get exactly the same issue.Erinn
C
9

The only thing that has worked for me (probably because I had inconsistencies with www. usage):

Paste this in to your .htaccess file:

<IfModule mod_headers.c>
<FilesMatch "\.(eot|font.css|otf|ttc|ttf|woff)$">
    Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
<IfModule mod_mime.c>
# Web fonts
AddType application/font-woff woff
AddType application/vnd.ms-fontobject eot

# Browsers usually ignore the font MIME types and sniff the content,
# however, Chrome shows a warning if other MIME types are used for the
# following fonts.
AddType application/x-font-ttf ttc ttf
AddType font/opentype otf

# Make SVGZ fonts work on iPad:
# https://twitter.com/FontSquirrel/status/14855840545
AddType     image/svg+xml svg svgz
AddEncoding gzip svgz

</IfModule>

# rewrite www.example.com → example.com

<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
</IfModule>

http://ce3wiki.theturninggate.net/doku.php?id=cross-domain_issues_broken_web_fonts

Cockeye answered 1/2, 2016 at 21:40 Comment(1)
Since your code was detailed, it took some time for me to go through it, I learned few things though. I applied portion of it to tweak my solution. It worked.Scrofulous
L
4

I had this same problem and this link provided the solution for me:

http://www.holovaty.com/writing/cors-ie-cloudfront/

The short version of it is:

  1. Edit S3 CORS config (my code sample didn't display properly)
    Note: This is already done in the original question
    Note: the code provided is not very secure, more info in the linked page.
  2. Go to the "Behaviors" tab of your distribution and click to edit
  3. Change "Forward Headers" from “None (Improves Caching)” to “Whitelist.”
  4. Add “Origin” to the "Whitelist Headers" list
  5. Save the changes

Your cloudfront distribution will update, which takes about 10 minutes. After that, all should be well, you can verify by checking that the CORS related error messages are gone from the browser.

Larkins answered 13/5, 2017 at 0:34 Comment(0)
F
4

For those using Microsoft products with a web.config file:

Merge this with your web.config.

To allow on any domain replace value="domain" with value="*"

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.webserver>
    <httpprotocol>
      <customheaders>
        <add name="Access-Control-Allow-Origin" value="domain" />
      </customheaders>
    </httpprotocol>
  </system.webserver>
</configuration>

If you don't have permission to edit web.config, then add this line in your server-side code.

Response.AppendHeader("Access-Control-Allow-Origin", "domain");
Freida answered 2/11, 2017 at 14:45 Comment(2)
Deserves a vote up for remembering us Windows users.Antilogarithm
I'm using asp.net core, how do I add this to the appsettings.json file?Peter
F
4

For AWS S3, setting the Cross-origin resource sharing (CORS) to the following worked for me:

[
    {
        "AllowedHeaders": [
            "Authorization"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]
Fonseca answered 14/2, 2021 at 2:14 Comment(3)
"AllowedOrigins": ["*"] <--- this really hurts!Ludie
@andreas, isn't this only a concern if you care if other sites load this content? Or is there something more risky here that I'm missing?Fonseca
Not that I am aware of. But it's really bad practice and can bite you in unexpected costs if others utilize your images. In case you have CloudFront in front of your S3 buckets, this can get expensive.Ludie
W
2

Late to the party, but I just ran into this problem and solved it with the following settings in my AWS bucket config (Permission tab). The requested format is not XML anymore but JSON:

[
    {
        "AllowedHeaders": [
            "Content-*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "https://www.yourdomain.example",
            "https://yourdomain.example"
        ],
        "ExposeHeaders": []
    }
]
Wolframite answered 30/8, 2014 at 0:50 Comment(0)
I
2

There is a nice writeup here.

Configuring this in nginx/apache is a mistake.
If you are using a hosting company you can't configure the edge.
If you are using Docker, the app should be self contained.

Note that some examples use connectHandlers but this only sets headers on the doc. Using rawConnectHandlers applies to all assets served (fonts/css/etc).

  // HSTS only the document - don't function over http.  
  // Make sure you want this as it won't go away for 30 days.
  WebApp.connectHandlers.use(function(req, res, next) {
    res.setHeader('Strict-Transport-Security', 'max-age=2592000; includeSubDomains'); // 2592000s / 30 days
    next();
  });

  // CORS all assets served (fonts/etc)
  WebApp.rawConnectHandlers.use(function(req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    return next();
  });

This would be a good time to look at browser policy like framing, etc.

Intuitionism answered 29/11, 2016 at 2:10 Comment(0)
U
0

Just add use of origin in your if you use node.js as server...

like this

  app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  next();
});

We Need response for origin

Upbeat answered 28/4, 2020 at 18:22 Comment(0)
P
0

If you want to allow all the fonts from a folder for a specific domain then you can use this:

  <location path="assets/font">
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="http://localhost:3000" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </location>

where assets/font is the location where all fonts are and http://localhost:3000 is the location which you want to allow.

Proboscidean answered 28/1, 2021 at 10:11 Comment(0)
H
0

Add this to your .htaccess file. This solved my problem.

<FilesMatch ".(eot|otf|ttf|woff|woff2)">
    Header always set Access-Control-Allow-Origin "*"
</FilesMatch>
Hypoploid answered 20/12, 2022 at 10:55 Comment(1)
I updated the title of this question to specifically mention this was an AWS CloudFront issueNurmi
P
-4

Working solution for heroku is here http://kennethjiang.blogspot.com/2014/07/set-up-cors-in-cloudfront-for-custom.html (quotes follow):

Below is exactly what you can do if you are running your Rails app in Heroku and using Cloudfront as your CDN. It was tested on Ruby 2.1 + Rails 4, Heroku Cedar stack.

Add CORS HTTP headers (Access-Control-*) to font assets

  • Add gem font_assets to Gemfile .
  • bundle install
  • Add config.font_assets.origin = '*' to config/application.rb . If you want more granular control, you can add different origin values to different environment, e.g., config/config/environments/production.rb
  • curl -I http://localhost:3000/assets/your-custom-font.ttf
  • Push code to Heroku.

Configure Cloudfront to forward CORS HTTP headers

In Cloudfront, select your distribution, under "behavior" tab, select and edit the entry that controls your fonts delivery (for most simple Rails app you only have 1 entry here). Change Forward Headers from "None" to "Whilelist". And add the following headers to whitelist:

Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Max-Age

Save it and that's it!

Caveat: I found that sometimes Firefox wouldn't not refresh the fonts even if CORS error is gone. In this case keep refreshing the page a few times to convince Firefox that you are really determined.

Polyhymnia answered 27/7, 2015 at 19:43 Comment(1)
Please avoid link-only answers. It will be helpful if you could copy relevant snippets out of the linked article into your answer. Thanks.Neighboring

© 2022 - 2024 — McMap. All rights reserved.