Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Amazon S3 CORS works with HTTP but not HTTPS

Tags:

amazon-s3

I can get Amazon S3 to pass CORS headers with http, but not with https. How do I get it to work with both? What if we're using Akamai as a CDN?

Here's my bucket configuration:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
   <CORSRule>
        <AllowedOrigin>https://*</AllowedOrigin>
        <AllowedOrigin>http://*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule> 
</CORSConfiguration>

Here's my test. The only difference between these is that one uses http, the other uses https. Both resources load just fine in the browser, but I would like to use them in a CORS setting where it could be https.

pnore@mbp> curl -i -H "Origin: http://example.com"   -H "Access-Control-Request-Method: GET" -H 'Pragma: no-cache' --verbose http://my.custom.domain/path/to/file/in/bucket | head -n 15
* Adding handle: conn: 0x7fee83803a00
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fee83803a00) send_pipe: 1, recv_pipe: 0
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* About to connect() to my.custom.domain port 80 (#0)
*   Trying 23.23.23.23...
* Connected to my.custom.domain (23.23.23.23) port 80 (#0)
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0> GET /path/to/file/in/bucket HTTP/1.1
> User-Agent: curl/7.30.0
> Host: my.custom.domain
> Accept: */*
> Origin: http://example.com
> Access-Control-Request-Method: GET
> Pragma: no-cache
>
< HTTP/1.1 200 OK
< x-amz-id-2: random
< x-amz-request-id: random
< Access-Control-Allow-Origin: http://example.com
< Access-Control-Allow-Methods: GET
< Access-Control-Max-Age: 3000
< Access-Control-Allow-Credentials: true
< Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
< Last-Modified: Tue, 10 Jun 2014 15:34:38 GMT
< ETag: "random"
< Accept-Ranges: bytes
< Content-Type: video/webm
< Content-Length: 8981905
* Server AmazonS3 is not blacklisted
< Server: AmazonS3
< Date: Fri, 19 Jun 2015 21:31:22 GMT
< Connection: keep-alive
<
{ [data not shown]
HTTP/1.1 200 OK
x-amz-id-2: random
x-amz-request-id: random
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Last-Modified: Tue, 10 Jun 2014 15:34:38 GMT
ETag: "random"
Accept-Ranges: bytes
Content-Type: video/webm
Content-Length: 8981905
Server: AmazonS3
Date: Fri, 19 Jun 2015 21:31:22 GMT
...

pnore@mbp> curl -i -H "Origin: http://example.com"   -H "Access-Control-Request-Method: GET" -H 'Pragma: no-cache' --verbose https://my.custom.comain/path/to/file/in/bucket | head -n 15
* Adding handle: conn: 0x7fd24380c000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fd24380c000) send_pipe: 1, recv_pipe: 0
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* About to connect() to my.custom.domain port 443 (#0)
*   Trying 23.23.23.23...
* Connected to my.custom.domain (23.23.23.23) port 443 (#0)
* TLS 1.2 connection using TLS_RSA_WITH_AES_256_CBC_SHA
* Server certificate: my.custom.domain
* Server certificate: GeoTrust SSL CA - G4
* Server certificate: GeoTrust Global CA
> GET /path/to/file/in/bucket HTTP/1.1
> User-Agent: curl/7.30.0
> Host: my.custom.domain
> Accept: */*
> Origin: http://example.com
> Access-Control-Request-Method: GET
> Pragma: no-cache
>
< HTTP/1.1 200 OK
< x-amz-id-2: 
< x-amz-request-id: 
< Last-Modified: Tue, 10 Jun 2014 15:34:38 GMT
< ETag: "random"
< Accept-Ranges: bytes
< Content-Type: video/webm
< Content-Length: 8981905
* Server AmazonS3 is not blacklisted
< Server: AmazonS3
< Date: Fri, 19 Jun 2015 21:31:29 GMT
< Connection: keep-alive
<
{ [data not shown]
HTTP/1.1 200 OK
x-amz-id-2: 
x-amz-request-id: 
Last-Modified: Tue, 10 Jun 2014 15:34:38 GMT
ETag: "random"
Accept-Ranges: bytes
Content-Type: video/webm
Content-Length: 8981905
Server: AmazonS3
Date: Fri, 19 Jun 2015 21:31:29 GMT
Connection: keep-alive

...

Note that the first request contains the desired Access-Control-Allow-Origin header, and the second does not.

I've also tried <AllowedOrigin>*</AllowedOrigin> and using different <CORSRule> blocks for each <AllowedOrigin>.

References I've checked:

  1. Getting S3 CORS Access-Control-Allow-Origin to dynamically echo requesting domain 1
  2. Amazon S3 CORS (Cross-Origin Resource Sharing) and Firefox cross-domain font loading 1
  3. Getting S3 CORS Access-Control-Allow-Origin to dynamically echo requesting domain
  4. Aws S3 Bucket CORS configuration is not saving properly
  5. http://blog.errorception.com/2014/11/enabling-cors-on-amazon-cloudfront-with.html
  6. Correct S3 + Cloudfront CORS Configuration?
  7. https://forums.aws.amazon.com/thread.jspa?messageID=377513
  8. How to Configure SSL for Amazon S3 bucket
  9. HTTPS for Amazon S3 static website
  10. SSL on Amazon S3 as "static website"
like image 981
Myer Avatar asked May 05 '26 05:05

Myer


1 Answers

I couldn't find documentation that explicitly mentioned it, but it appears that the CORS configuration for the bucket only allows one <AllowedOrigin> per <CORSRule> element entry. You are allowed up to 100 <CORSRule> entries in the configuration. Therefore, in order to get your configuration to support both http and https you should create two <CORSRule> entries, like so:

<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <CORSRule>
    <AllowedOrigin>https://*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule> 
  <CORSRule>
    <AllowedOrigin>http://*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule> 
</CORSConfiguration>

FWIW, I have not tried it, but the configuration may also support a protocol agnostic format, e.g. simply <AllowedOrigin>//*</AllowedOrigin>.

like image 131
coryfoo Avatar answered May 07 '26 19:05

coryfoo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!