aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
89 stars 79 forks source link

REST API backend missing x-amz-content-sha256 allowed header for CORS #519

Open ragingsquirrel3 opened 2 years ago

ragingsquirrel3 commented 2 years ago

Before opening, please confirm:

How did you install the Amplify CLI?

npm

If applicable, what version of Node.js are you using?

v12.22.12

Amplify CLI Version

8.0.2

What operating system are you using?

mac

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

After reproducing this bug, I manually did the following to get it working as expected (which helps to clarify expected behavior).

I went into API gateway and under the CORS enabling part like on https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors-console.html and added "x-amz-content-sha256" to the comma-separated list of allowed headers.

Amplify Categories

api

Amplify Commands

add

Describe the bug

I noticed this while working on web support for amplify-flutter. I suspect you could repro with amplify JS but I haven't tried. The same code has no issue in android/ios but fails only in web with CORS. I was sure to uncomment the CORS headers in lambda JS code.

When provisioning a REST API backend to use on the web, I get a CORS error for any request that has a body in IAM auth mode (post, put, patch, delete). If I do a GET or HEAD request (no body), I see there is a preflight request and then the request is successful. If I do a request with a body, there is a preflight request and then a CORS error that prevents that actual request from being sent. I don't have the exact chrome error on hand, but it basically says that header "x-amz-content-sha256" is not allowed. When I look at the response from the preflight request, I see many headers related to signing are allowed, but "x-amz-content-sha256" is not included in that list. This all explains the behavior because that header is only present on requests with bodies as it relates to signing the body content as explained on https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html. The dart sigv4 implementation we have will add this as a header when the canonical request has a body, as expected. It appears that the list of headers included in the CORS allowlist from CLI (or wherever it comes from) only works for GET or HEAD.

As I mentioned, I was able to manually add that header to the preflight allowlist response in the CORS part of API gateway and then it worked.

Expected behavior

I would expect the CLI to include "x-amz-content-sha256" in the list Access-Control-Allow-Headers in the CORS section for me (along with the other headers already there) for me when I provision the backend as it seems odd to have it configure all but one of the headers required.

Reproduction steps

  1. configure a backend with REST and auth, allow unauthenticated logins and require credentials from unauthenticated logins to access the REST endpoint.
  2. Use the hello world lambda template for REST, uncomment the part about CORS headers in the JS code there.
  3. This part will be hard for others, but I used a prototype of amplify-flutter with REST API support in dart that can run flor flutter in web with flutter run -d chrome. I think you could do this with a JS app.
  4. Send a POST request to the endpoint that has a body.

You will get a CORS error in the browser.

GraphQL schema(s)

```graphql # Put schemas below this line ```

Log output

``` # Put your logs below this line ```

Additional information

No response

josefaidt commented 2 years ago

Hey @ragingsquirrel3 :wave: thanks for raising this! I've marked this as a feature request to include the new CORS header along with the defaults, and will transfer this over to our API repo for further evaluation 🙂