Skip to content

Commit

Permalink
fix: Allow the base64Encoded field in REST Api, skip validation of un…
Browse files Browse the repository at this point in the history
…known fields and validate missing statusCode for Http Api (aws#2941)

* fix API Gateway emulator:
 - skip validating the non allowed fields for Http Api Gateway, as it always skip the unknown fields
 - add base64Encoded as an allowed field for Rest Api gateway
 - base64 decoding will be always done for Http API gateway if the lambda response isBase64Encoded is true regardless the content-type
 - validate if statusCode is missing in case of Http API, and payload version 1.0

* - accept "true", "True", "false", "False" as valid isBase64Encoded values.
- Validate on other isBase64Encoded Values
- add more integration && unit test cases

* fix lint && black issues

* use smaller image to test Base64 response
  • Loading branch information
moelasmar committed Jul 1, 2021
1 parent c04621a commit 5854717
Show file tree
Hide file tree
Showing 7 changed files with 577 additions and 70 deletions.
71 changes: 54 additions & 17 deletions samcli/local/apigw/local_apigw_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def _request_handler(self, **kwargs):
)
else:
(status_code, headers, body) = self._parse_v1_payload_format_lambda_output(
lambda_response, self.api.binary_media_types, request
lambda_response, self.api.binary_media_types, request, route.event_type
)
except LambdaResponseParseException as ex:
LOG.error("Invalid lambda response received: %s", ex)
Expand Down Expand Up @@ -379,13 +379,14 @@ def get_request_methods_endpoints(flask_request):

# Consider moving this out to its own class. Logic is started to get dense and looks messy @jfuss
@staticmethod
def _parse_v1_payload_format_lambda_output(lambda_output: str, binary_types, flask_request):
def _parse_v1_payload_format_lambda_output(lambda_output: str, binary_types, flask_request, event_type):
"""
Parses the output from the Lambda Container
:param str lambda_output: Output from Lambda Invoke
:param binary_types: list of binary types
:param flask_request: flash request object
:param event_type: determines the route event type
:return: Tuple(int, dict, str, bool)
"""
# pylint: disable-msg=too-many-statements
Expand All @@ -397,6 +398,9 @@ def _parse_v1_payload_format_lambda_output(lambda_output: str, binary_types, fla
if not isinstance(json_output, dict):
raise LambdaResponseParseException(f"Lambda returned {type(json_output)} instead of dict")

if event_type == Route.HTTP and json_output.get("statusCode") is None:
raise LambdaResponseParseException(f"Invalid API Gateway Response Key: statusCode is not in {json_output}")

status_code = json_output.get("statusCode") or 200
headers = LocalApigwService._merge_response_headers(
json_output.get("headers") or {}, json_output.get("multiValueHeaders") or {}
Expand All @@ -405,7 +409,8 @@ def _parse_v1_payload_format_lambda_output(lambda_output: str, binary_types, fla
body = json_output.get("body")
if body is None:
LOG.warning("Lambda returned empty body!")
is_base_64_encoded = json_output.get("isBase64Encoded") or False

is_base_64_encoded = LocalApigwService.get_base_64_encoded(event_type, json_output)

try:
status_code = int(status_code)
Expand All @@ -422,8 +427,10 @@ def _parse_v1_payload_format_lambda_output(lambda_output: str, binary_types, fla
f"Non null response bodies should be able to convert to string: {body}"
) from ex

invalid_keys = LocalApigwService._invalid_apig_response_keys(json_output)
if invalid_keys:
invalid_keys = LocalApigwService._invalid_apig_response_keys(json_output, event_type)
# HTTP API Gateway just skip the non allowed lambda response fields, but Rest API gateway fail on
# the non allowed fields
if event_type == Route.API and invalid_keys:
raise LambdaResponseParseException(f"Invalid API Gateway Response Keys: {invalid_keys} in {json_output}")

# If the customer doesn't define Content-Type default to application/json
Expand All @@ -432,17 +439,51 @@ def _parse_v1_payload_format_lambda_output(lambda_output: str, binary_types, fla
headers["Content-Type"] = "application/json"

try:
if LocalApigwService._should_base64_decode_body(binary_types, flask_request, headers, is_base_64_encoded):
# HTTP API Gateway always decode the lambda response only if isBase64Encoded field in response is True
# regardless the response content-type
# Rest API Gateway depends on the response content-type and the API configured BinaryMediaTypes to decide
# if it will decode the response or not
if (event_type == Route.HTTP and is_base_64_encoded) or (
event_type == Route.API
and LocalApigwService._should_base64_decode_body(
binary_types, flask_request, headers, is_base_64_encoded
)
):
body = base64.b64decode(body)
except ValueError as ex:
LambdaResponseParseException(str(ex))

return status_code, headers, body

@staticmethod
def get_base_64_encoded(event_type, json_output):
# The following behaviour is undocumented behaviour, and based on some trials
# Http API gateway checks lambda response for isBase64Encoded field, and ignore base64Encoded
# Rest API gateway checks first the field base64Encoded field, if not exist, it checks isBase64Encoded field

if event_type == Route.API and json_output.get("base64Encoded") is not None:
is_base_64_encoded = json_output.get("base64Encoded")
field_name = "base64Encoded"
elif json_output.get("isBase64Encoded") is not None:
is_base_64_encoded = json_output.get("isBase64Encoded")
field_name = "isBase64Encoded"
else:
is_base_64_encoded = False
field_name = "isBase64Encoded"

if isinstance(is_base_64_encoded, str) and is_base_64_encoded in ["true", "True", "false", "False"]:
is_base_64_encoded = is_base_64_encoded in ["true", "True"]
elif not isinstance(is_base_64_encoded, bool):
raise LambdaResponseParseException(
f"Invalid API Gateway Response Key: {is_base_64_encoded} is not a valid" f"{field_name}"
)

return is_base_64_encoded

@staticmethod
def _parse_v2_payload_format_lambda_output(lambda_output: str, binary_types, flask_request):
"""
Parses the output from the Lambda Container
Parses the output from the Lambda Container. V2 Payload Format means that the event_type is only HTTP
:param str lambda_output: Output from Lambda Invoke
:param binary_types: list of binary types
Expand Down Expand Up @@ -487,21 +528,15 @@ def _parse_v2_payload_format_lambda_output(lambda_output: str, binary_types, fla
f"Non null response bodies should be able to convert to string: {body}"
) from ex

# API Gateway only accepts statusCode, body, headers, and isBase64Encoded in
# a response shape.
# Don't check the response keys when inferring a response, see
# https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.v2.
invalid_keys = LocalApigwService._invalid_apig_response_keys(json_output)
if "statusCode" in json_output and invalid_keys:
raise LambdaResponseParseException(f"Invalid API Gateway Response Keys: {invalid_keys} in {json_output}")

# If the customer doesn't define Content-Type default to application/json
if "Content-Type" not in headers:
LOG.info("No Content-Type given. Defaulting to 'application/json'.")
headers["Content-Type"] = "application/json"

try:
if LocalApigwService._should_base64_decode_body(binary_types, flask_request, headers, is_base_64_encoded):
# HTTP API Gateway always decode the lambda response only if isBase64Encoded field in response is True
# regardless the response content-type
if is_base_64_encoded:
# Note(xinhol): here in this method we change the type of the variable body multiple times
# and confused mypy, we might want to avoid this and use multiple variables here.
body = base64.b64decode(body) # type: ignore
Expand All @@ -511,8 +546,10 @@ def _parse_v2_payload_format_lambda_output(lambda_output: str, binary_types, fla
return status_code, headers, body

@staticmethod
def _invalid_apig_response_keys(output):
def _invalid_apig_response_keys(output, event_type):
allowable = {"statusCode", "body", "headers", "multiValueHeaders", "isBase64Encoded", "cookies"}
if event_type == Route.API:
allowable.add("base64Encoded")
invalid_keys = output.keys() - allowable
return invalid_keys

Expand Down
49 changes: 46 additions & 3 deletions tests/integration/local/start_api/test_start_api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import base64
import uuid
import random

Expand Down Expand Up @@ -382,14 +383,14 @@ def test_valid_v2_lambda_integer_response(self):

@pytest.mark.flaky(reruns=3)
@pytest.mark.timeout(timeout=600, method="thread")
def test_invalid_v2_lambda_response(self):
def test_v2_lambda_response_skip_unexpected_fields(self):
"""
Patch Request to a path that was defined as ANY in SAM through AWS::Serverless::Function Events
"""
response = requests.get(self.url + "/invalidv2response", timeout=300)

self.assertEqual(response.status_code, 502)
self.assertEqual(response.json(), {"message": "Internal server error"})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json(), {"hello": "world"})

@pytest.mark.flaky(reruns=3)
@pytest.mark.timeout(timeout=600, method="thread")
Expand Down Expand Up @@ -538,6 +539,48 @@ def test_binary_response(self):
self.assertEqual(response.headers.get("Content-Type"), "image/gif")
self.assertEqual(response.content, expected)

@pytest.mark.flaky(reruns=3)
@pytest.mark.timeout(timeout=600, method="thread")
def test_non_decoded_binary_response(self):
"""
Binary data is returned correctly
"""
expected = base64.b64encode(self.get_binary_data(self.binary_data_file))

response = requests.get(self.url + "/nondecodedbase64response", timeout=300)

self.assertEqual(response.status_code, 200)
self.assertEqual(response.headers.get("Content-Type"), "image/gif")
self.assertEqual(response.content, expected)

@pytest.mark.flaky(reruns=3)
@pytest.mark.timeout(timeout=600, method="thread")
def test_decoded_binary_response_base64encoded_field(self):
"""
Binary data is returned correctly
"""
expected = self.get_binary_data(self.binary_data_file)

response = requests.get(self.url + "/decodedbase64responsebas64encoded", timeout=300)

self.assertEqual(response.status_code, 200)
self.assertEqual(response.headers.get("Content-Type"), "image/gif")
self.assertEqual(response.content, expected)

@pytest.mark.flaky(reruns=3)
@pytest.mark.timeout(timeout=600, method="thread")
def test_decoded_binary_response_base64encoded_field_is_priority(self):
"""
Binary data is returned correctly
"""
expected = base64.b64encode(self.get_binary_data(self.binary_data_file))

response = requests.get(self.url + "/decodedbase64responsebas64encodedpriority", timeout=300)

self.assertEqual(response.status_code, 200)
self.assertEqual(response.headers.get("Content-Type"), "image/gif")
self.assertEqual(response.content, expected)


class TestStartApiWithSwaggerHttpApis(StartApiIntegBaseClass):
template_path = "/testdata/start_api/swagger-template-http-api.yaml"
Expand Down
Binary file modified tests/integration/testdata/start_api/binarydata.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def invalid_hash_response(event, context):


def base64_response(event, context):
gifImageBase64 = "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" # NOQA
gifImageBase64 = "R0lGODdhAQABAJEAAAAAAP///wAAAAAAACH5BAkAAAIALAAAAAABAAEAAAICRAEAOw==" # NOQA

return {
"statusCode": 200,
Expand Down
36 changes: 34 additions & 2 deletions tests/integration/testdata/start_api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import sys
import time

GIF_IMAGE_BASE64 = "R0lGODdhAQABAJEAAAAAAP///wAAAAAAACH5BAkAAAIALAAAAAABAAEAAAICRAEAOw=="


def handler(event, context):
return {"statusCode": 200, "body": json.dumps({"hello": "world"})}
Expand Down Expand Up @@ -70,11 +72,41 @@ def invalid_hash_response(event, context):


def base64_response(event, context):
gifImageBase64 = "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" # NOQA

return {
"statusCode": 200,
"body": gifImageBase64,
"body": GIF_IMAGE_BASE64,
"isBase64Encoded": True,
"headers": {"Content-Type": "image/gif"},
}


def base64_with_False_isBase64Encoded_response(event, context):

return {
"statusCode": 200,
"body": GIF_IMAGE_BASE64,
"isBase64Encoded": False,
"headers": {"Content-Type": "image/gif"},
}


def base64_with_True_Base64Encoded_response(event, context):

return {
"statusCode": 200,
"body": GIF_IMAGE_BASE64,
"base64Encoded": True,
"headers": {"Content-Type": "image/gif"},
}


def base64_with_Base64Encoded_priority_response(event, context):

return {
"statusCode": 200,
"body": GIF_IMAGE_BASE64,
"base64Encoded": False,
"isBase64Encoded": True,
"headers": {"Content-Type": "image/gif"},
}
Expand Down
48 changes: 48 additions & 0 deletions tests/integration/testdata/start_api/swagger-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,30 @@ Resources:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Base64ResponseFunction.Arn}/invocations

"/nondecodedbase64response":
get:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Base64ResponseFunctionWithFalseIsBase64EncodedField.Arn}/invocations

"/decodedbase64responsebas64encoded":
get:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Base64ResponseFunctionWithTrueBase64EncodedField.Arn}/invocations

"/decodedbase64responsebas64encodedpriority":
get:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Base64ResponseFunctionWithBase64EncodedFieldPriority.Arn}/invocations

"/echobase64eventbody":
post:
x-amazon-apigateway-integration:
Expand Down Expand Up @@ -124,6 +148,30 @@ Resources:
CodeUri: .
Timeout: 600

Base64ResponseFunctionWithFalseIsBase64EncodedField:
Type: AWS::Serverless::Function
Properties:
Handler: main.base64_with_False_isBase64Encoded_response
Runtime: python3.6
CodeUri: .
Timeout: 600

Base64ResponseFunctionWithTrueBase64EncodedField:
Type: AWS::Serverless::Function
Properties:
Handler: main.base64_with_True_Base64Encoded_response
Runtime: python3.6
CodeUri: .
Timeout: 600

Base64ResponseFunctionWithBase64EncodedFieldPriority:
Type: AWS::Serverless::Function
Properties:
Handler: main.base64_with_Base64Encoded_priority_response
Runtime: python3.6
CodeUri: .
Timeout: 600

EchoBase64EventBodyFunction:
Type: AWS::Serverless::Function
Properties:
Expand Down
Loading

0 comments on commit 5854717

Please sign in to comment.