cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Surveyor II

Safari CORS preflight cache OPTIONS method on image uploads (AWS S3 and CORSRules config)

Issue:

Safari failing its preflight CORS check on cached images, where the image src is a redirect (Canvas Instructure URL redirect to an AWS S3 bucket).

To duplicate:

1. In Safari (v13.2 with file caching on, Desktop or iOS), Go to site https://cidilabs.instructure.com/courses/3/pages/upload-slash-embed-image-test. I do not control this public page, my apologies if it becomes a broken link. If you have access to a Canvas LMS, you can duplicate this page by uploading an image through the Canvas image upload tool to a module page. Canvas embeds uploaded images as a redirect link to an S3 bucket.
2. Then refresh that page, to initiate a preflight CORS request on the cached image, to see the broken image link.

This is the console error:

FetchEvent.respondWith received an error:
TypeError: Cross-origin redirection to <actual image source> 
denied by Cross-Origin Resource Sharing policy: 
Origin <hosted page containing the image src redirect to image source> 
is not allowed by Access-Control-Allow-Origin.


The original CORS request is fine. It's only the preflight check on cached resource that fails. I'm hoping it's a Safari bug/fixable, because if it's a feature, Chrome & Firefox might follow with the weird behavior. The other possibility is that additional CORS Rules on the server for OPTIONS methods with headers might resolve it for Safari (and future releases of Firefox and Chrome).


Workarounds (non-optimal):

  • Always open a private browser when using a page with an embedded CORS redirect image. The issue only happens when the image is cached. [Not a practical solution for users]
  • Add a terminating solidus (forward slash) to all cachable resources that are CORS redirect paths. The issue only happens when the redirect path looks like a file not a directory. [I'm torn about this being bad style for image src URL. But, because the image src is really a redirect and not really a file anyway, I think it's not totally bad to show it as a dir.] ** the most practical of the bad workarounds
  • Make the image src URL a DIFFERENT host than the page it's embedded in. The issue only seems to happen if the cached image src redirect URL is the same host as the web page. [This is so weird! Maybe, some crazy way Safari caches host page resources.]
  • Use FireFox or Chrome when going to a page with a CORS image src redirect. The issue only happens with Safari. [Terrible workaround, cuts out a lot of users]

The Question!

Finally, the QUESTION to the community: Are people addressing this issue by adjusting their CORSrules config on their Canvas server and/or the AWS S3 buckets?

For example, do you have cors rules that include the OPTIONS method, AllowOrigin, and AllowHeaders?

<CORSConfiguration>
 <CORSRule>
  ... PUT, DELETE, POST, etc
  ....
 <CORSRule>
   <AllowedMethod>GET</AllowedMethod>
   <AllowedMethod>OPTIONS</AllowedMethod>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
</CORSConfiguration>

 

Related links:

The answer on this link is not working for our issue of Canvas uploaded images: https://community.canvaslms.com/t5/Question-Forum/Uploaded-images-no-longer-function-in-Safari/m-p/3...

I asked the same question about CORS rules for Canvas and S3 here https://github.com/instructure/canvas-lms/issues/1183

An alternative possible help from jQuery library to remove the forced addition of `X-Requested-With: XMLHttpRequest`  header on OPTIONS methods https://github.com/jquery/jquery/issues/4788

 

0 Kudos
4 Replies
Highlighted
Surveyor II

Regarding the jQuery reference from above, I found that using Safari Inspector, I can add a breakpoint to the jQuery (jQuery v1.7.2) `xhr.send( ( s.hasContent && s.data ) || null );`. Then, reload the page and let the code hang and time out on that line. This prevents the OPTIONS method call from being sent to Canvas. The image loads successfully, with correct headers. The images continue to load successfully, from now on, on every new page refresh.

This implies that the OPTIONS call from this old version of jQuery might be causing problems with Safari image redirect cache.

There are multiple versions of jQuery and other code performing GETs which may contribute to the problem with Safari and Canvas uploaded images.

0 Kudos
Highlighted
Surveyor II

Related to the CORS setup of AWS S3 image bucket for Canvas, can you verify if "Vary: Origin" is added to headers from the S3 bucket?

Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

"CORS and caching"
If the server sends a response with an Access-Control-Allow-Origin value that is an explicit origin (rather than the "*" wildcard), then the response should also include a Vary response header with the value Origin — to indicate to browsers that server responses can differ based on the value of the Origin request header.

Access-Control-Allow-Origin: https://developer.mozilla.org
Vary: Origin

0 Kudos
Highlighted
Surveyor II

I created a ticket with additional discussion https://github.com/instructure/canvas-lms/pull/1700
The ticket suggests mitigating the issue on the client side while continuing to debug the server side.

0 Kudos
Highlighted
Surveyor II

The following curl checked Access-Control-Allow-Methods for instructure-uploads.s3.amazonaws.com as recommended in AWS S3 ticket referenced below. The OPTIONS method is not listed as one of the accepted methods. Can someone verify if the Safari preflight OPTIONS method is allowed on https://instructure-uploads.s3.amazonaws.com?

Access-Control-Allow-Methods: GET, PUT, POST, OPTIONS <------ missing?

$ curl -H "origin: any" -v "https://instructure-uploads.s3.amazonaws.com"

> GET / HTTP/1.1
> Host: instructure-uploads.s3.amazonaws.com

< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, PUT, POST
< Access-Control-Max-Age: 3000
< Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
< x-amz-bucket-region: us-east-1
< Server: AmazonS3

 

"By default, CloudFront allows only the GET and HEAD methods, but some web browsers [i.e. Safari] might issue requests for the OPTIONS method."

The CloudFront distribution's cache behavior allows the OPTIONS method for HTTP requests

If you're still seeing errors after you update your CORS policy and forward the appropriate headers, try allowing the OPTIONS HTTP method in your distribution's cache behavior. By default, CloudFront allows only the GET and HEAD methods, but some web browsers might issue requests for the OPTIONS method.

To enable the OPTIONS method on your CloudFront distribution, follow these steps:

  1. Open your distribution from the CloudFront console.
  2. Choose the Behaviors tab.
  3. Choose Create Behavior, or choose an existing behavior, and then choose Edit.
  4. For Allowed HTTP Methods, select GET, HEAD, OPTIONS.


https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/

 

0 Kudos
Top Kudoed Authors
Labels