Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS GET request with body rejected by CloudFront

I'm build an API using AWS SAM (Lambda & API Gateway) whose contract is defined by a 3rd party.

The 3rd party calls my API with a GET request that contains JSON in the body. However, when a request is sent to the API with a body it gets rejected by CloudFront.

This is the request:

curl -X GET -H "Content-Type: application/json" --data '{"hello":"world"}' https://my-api.execute-api.us-east-2.amazonaws.com/Prod/my-api

This is the response:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
    <HEAD>
        <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
        <TITLE>ERROR: The request could not be satisfied</TITLE>
    </HEAD>
    <BODY>
        <H1>403 ERROR</H1>
        <H2>The request could not be satisfied.</H2>
        <HR noshade size="1px">
Bad request.


        <BR clear="all">
        <HR noshade size="1px">
        <PRE>
Generated by cloudfront (CloudFront)
Request ID: 1p0St_-e3noQL-2uMxeB_2I6lkMr1mg5afvxJRmVpCdnG67Vgnhj9w==
</PRE>
        <ADDRESS></ADDRESS>
    </BODY>
</HTML>

Checking the logs, the request never hits API Gateway or the Lambda function. However, if I remove the body from the request, then it hits the Lambda function and I get the appropriate error message from the API (telling the caller that the expected body is missing.)

curl -X GET -H "Content-Type: application/json" https://my-api.execute-api.us-east-2.amazonaws.com/Prod/my-api

I'm using basic configuration of API Gateway via a SAM template. This is the relevant section:

MyApiFunction:
  Type: AWS::Serverless::Function
  Properties:
    CodeUri: bin/main.zip
    Handler: main
    Runtime: go1.x
    Tracing: Active
    Role: !Sub ${MyApiLambdaExecutorRole.Arn}
    Events:
      CatchAll:
        Type: Api
        Properties:
          Path: /my-api
          Method: GET
like image 530
Stefan Moser Avatar asked Dec 14 '18 21:12

Stefan Moser


People also ask

How do I resolve the error the request could not be satisfied request blocked from CloudFront?

To resolve the Request Blocked error when the default action is Block, review the requests to be sure that they match the conditions for any AWS WAF rules with Action set to Allow. If valid requests don't match any existing rules that allow requests, then create a rule that allows the requests.

Why is Amazon CloudFront blocking me from websites?

This will occur because of below reasons: The request is initiated over HTTP, but the CloudFront distribution is configured to only allow HTTPS requests. The requested alternate domain name (CNAME) isn't associated with the CloudFront distribution.


1 Answers

GET requests cannot contain a request body on CloudFront. Try using POST instead.

If you want to send limited data in a GET request, you can use query parameters.

You can see in the AWS Docs that this isn't possible here:

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#RequestCustom-get-body

If a viewer GET request includes a body, CloudFront returns an HTTP status code 403 (Forbidden) to the viewer.

You could perhaps use an EC2 instance or other service that doesn't use API Gateway to handle the request.

like image 100
Dave S Avatar answered Nov 13 '22 17:11

Dave S