I am working on a project where protecting resources (here: webfonts) is a legal requirement and CORS is considered sufficient. Accessing CORS protected resources seems impossible through the AMP CDN.
For protected resources, we check the Origin:
request header against a regular expression and generate a matching Access-Control-Allow-Origin:
response header for a match plus Vary: Origin
always.
In essence (simplified, reduced example):
curl -H 'Orgin: https://allowed.domain' -I https://site/.../font.woff2
->
HTTP/1.1 200 OK
Cache-Control: public, immutable, max-age=26680348
Access-Control-Allow-Origin: https://allowed.domain
Vary: Origin, Accept-Encoding
curl -H 'Orgin: https://evil.domain' -I https://site/.../font.woff2
->
HTTP/1.1 200 OK
Cache-Control: public, immutable, max-age=26680348
Vary: Origin, Accept-Encoding
This is plain simple CORS.
Now when I fire the same request against the corresponding AMP CDN URL...
curl -H 'Orgin: https://allowed.domain' -I https://site.cdn.ampproject.org/r/s/site/.../font.woff2
I see a request coming in with
User-Agent: Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Google-AMPHTML)
from an IP resolving to google-proxy-*.google.com
, but neither an Origin:
nor an AMP-Same-Origin:
request header. Yet the way I read https://github.com/ampproject/amphtml/blob/master/spec/amp-cors-requests.md#pseudo-cors-logic I should expect at least either.
It does not seem to matter if Origin: ends with cdn.ampproject.org
, the cdn does not seem to forward it.
Consequently, our origin responds with 200 and no A-C-A-O as illustrated above.
Even more confusingly, the amp cdn sends this response downstream:
HTTP/2 404
access-control-allow-origin: *
x-content-type-options: nosniff
...
So, how is CORS supposed to work with resources on the AMP CDN?
This was an actual AMP CDN issue. I have worked 1:1 with contacts from google, who have resolved the issue.
Additionally, our origin did not send a Content-Type
response header, which is required.