Request Validation with API Gateway Models

Introduction

Congratulations, you have just been hired by your dream company and you have gained access to contribute to that codebase you have been dreaming of working on, or you probably started the code base from scratch, or you are just tinkering with APIs, or...(your specific scene at this time🙂). It is a REST API developed/built using Amazon API Gateway, AWS Lambda, and NodeJS runtime.

"Uh-Oh! Do I See a Potential Problem Lurking Around the Corner?"

Within this awesome codebase, you probably notice that the API Endpoint configurations either do not have a request body validation layer, or you find that there are code blocks that are used to validate the request body instead which looks like this:

  
const { email, password, name, ... } = JSON.parse(event.body);`
if (!email) {
	return {
		statusCode: 400,
		message: "Email is required!☹️",
		...
	}
}
  

While this code block looks clean and probably not DRY (because there's likely an if(!password)... somewhere down the line), every request with a valid, invalid, or worse, corrupted data, is allowed to trigger your function because this awesome validation happens within the Lambda itself. Alas, this approach might not be the most ideal to validate your API request body.

While APIs facilitate seamless communication and data/information exchange between various systems and applications, there are certain measures and approaches to be taken to ensure the security and integrity of these API interactions. It’s important incoming requests hold fast to the expected structure and constraints BEFORE your requests invoke or trigger your Lambda function. This is fundamental to API Security.

If you have used NodeJS with/without typescript to build APIs, you might be familiar with packages like zod for typescript, express-validator, etc. These are used to validate request payloads before the respective functions are invoked. However, Amazon API Gateway does not directly support integrating with these packages.

Amazon API Gateway has a feature configuration called Models. These are essentially JSON Schemas/Objects which are configured on the API Gateway endpoint to validate the request payload before invoking the downstream resource.

What are JSON Schemas?

JSON Schema is a vocabulary that allows software developers and engineers to annotate and validate JSON documents by providing a standardized way to define the structure, format, and constraints of JSON data.

This enables developers to describe the expected shape of the payload including object properties, data types, and validation rules.

You can learn more about JSON Schema definitions, drafts, structures, and usage here.

Implementing Request Validation In API Gateway

Amazon API Gateway offers native support for JSON Schema Validation in its Models feature; allowing you to seamlessly integrate request payload validation into your API Gateway workflows.

API Gateway Models provides a means to strictly define the accepted payload to your requests using the JSON Schema Syntax which is pretty straightforward.

Here's an example of a typical Model definition:

  
{
	"$schema": "http://json-schema.org/draft-04/schema#",
	"title": "SignUpModel",
	"type": "object",
	"properties": {
		"name": { 
			"type": "string",
			"pattern": "^[a-zA-Z]+$",
			"maxLength": "20"
		},
		"email": { "type": "string", "format": "email" },
		"password": { 
			"type": "string",
			"pattern": "/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d])(?!.*\s).{8,15}$/g"
		},
		"state": {
			"type": "string",
			"minLength": "3"
		},
		"reference": { "type": "string" },
	},
	"required": ["name", "email", "password" ]
}
  

"$schema" indicates the draft the JSON Schema standard would follow, and "properties" is a JSON Schema keyword that contains all the fields in the request payload to be validated. It must be an object.

The fields defined in the "properties" ensure that request payloads must:

  • Contain a defined non-empty string field name which must contain only alphabet characters, and must not exceed 20 characters in length
  • Contain a defined non-empty string field email which must be of type email. JSON Schema supports a list of formats for strings which you can find here
  • Contain a defined non-empty string field password which must be at least 8 but no more than 15 characters long, and must contain at least one upper case and lower case letter, a number, and a symbol excluding white spaces as specified in the pattern keyword which accepts Regular Expressions to be applied to the field.
  • If the field state is defined, it must be a string with a minimum of three characters
  • A non-required field reference which must contain only strings including an empty string ""

For detailed information on JSON Schema draft follow this link.

Let's see the practical application API Gateway Models using Serverless Framework. Let’s assume we have a Lambda function that puts user metadata into DynamoDB after a successful signup. The following configurations add a request validation layer to the APIGateway event that acts as a trigger to the lambda function.

Configuration

serverless.yml

  
functions:
	handler: src/functions/signup.handler
	iamRoleStatements:
	  - Effect: Allow
	    Action:
	      - dynamodb:PutItem
	    Resource: "arn:aws:dynamodb:${aws:region}:${aws:accountId}:table/yourTableName"
	events:
	  - http:
	      path: signup/
	      method: POST
	      cors: true
	      request:
	        schemas:
	          application/json:
	            schema: ${file(./src/schemas/signup.json)}
	            name: SignUpModel
  

The validation config starts with the request field.

The Serverless Framework pulls the configuration from there to create the Models on API Gateway. you can either define the JSON schema explicitly on the schema field or pass in a file path where your JSON has been predefined. name is simply the name to be attributed to the Model.

With this configuration in place, any requests with a payload that do not explicitly conform to the defined properties in the Model are rejected and treated as 400 Bad Request.

Limitations of API Gateway Models

  • Limited Custom Error Messages: Currently, the custom error you can throw/return for invalid requests applies to the entire payload. For example, if validation fails due to the state field, you cannot catch and throw that the state field specifically has an invalid format. You can only define a custom error which is applied generally on request validation failure.
  • Limited Support on Schemas: APIGateway models are defined using the JSON Schema draft #4, this might support only data types available on this draft, and may not cover complex scenarios
  • No added validation logic beyond what JSON Schema provides.

For a better understanding of APIGateway Models and request validation, feel free to check out the official AWS Documentation.

Conclusion

Implementing request validation in API Gateway using JSON Schema models enhances security by enforcing strict validation rules which can help mitigate schema poisoning and injection attacks on your server.

Whether you're building a new API or enhancing an existing one, request validation is a critical step towards safeguarding your API infrastructure and protecting against potential threats.

Happy Coding and Sayonara😊

References

  1. JSON Schema official website
  2. Amazon API Gateway Models Documentation
  3. Amazon API Gateway Request Validation Documentation
Serverless Handbook
Access free book

The dream team

At Serverless Guru, we're a collective of proactive solution finders. We prioritize genuineness, forward-thinking vision, and above all, we commit to diligently serving our members each and every day.

See open positions

Looking for skilled architects & developers?

Join businesses around the globe that trust our services. Let's start your serverless journey. Get in touch today!
Ryan Jones - Founder
Ryan Jones
Founder
Speak to a Guru
arrow
Edu Marcos - CTO
Edu Marcos
Chief Technology Officer
Speak to a Guru
arrow
Mason Toberny
Mason Toberny
Head of Enterprise Accounts
Speak to a Guru
arrow

Join the Community

Gather, share, and learn about AWS and serverless with enthusiasts worldwide in our open and free community.