In the first part of this blog, we had covered the security aspects of Spring Boot Microservices and how to inject them into your code level to generate higher quality OAS (Swagger) files. In this second part, we will cover aspects regarding attributes, operations, and data.
Data Validation for Secure APIs
You must be aware that according to the way you have declared the parameters, response headers, definitions, and schemas in your OAS (Swagger) file, you might be able to get some data exposure or potential security scenario that can be exploited.
Figure 1 – Data Validation Problems and Issues in the OAS (Swagger) file
Using Spring Boot and Springfox, you can avoid such discrepancies and issues in your contract, allowing your API to reach a much higher audit score. Please, refer to the following best practices in this post.
Best Practice #1: Schemas PATTERN/MIN LENGTH/MAX LENGTH
This is very important in order to avoid attacks trying to break the kind of data that your API is ready to operate, please see the following code snippet:
Code Definition
@ApiModel(description = "Class representing a person tracked by the application.")
public class Person {
@Min(5)
@Max(50)
@NotNull
@NotBlank
@Pattern(regexp = Constants.ID_REGEX)
private int id;
@NotNull
@NotBlank
@Pattern(regexp = Constants.GENERIC_NAME_REGEX)
@Size(min = 5, max = 30)
private String firstName;
Swagger 2.0 Equivalent
"firstName": {
"type": "string",
"minLength": 5,
"maxLength": 30,
"pattern": "^[a-zA-Z\\s_\\-]{2,50}$"
},
"id": {
"type": "integer",
"format": "int32",
"minimum": 5,
"maximum": 50,
"exclusiveMinimum": false,
"exclusiveMaximum": false
},
The code above prevents that for an attribute id accept any integer smaller than 5 or larger than 50, as well as it says that it can’t be null or blank, as well as it comes with a standard regular expression for accepting an integer value. For the attribute firstName, it has a valid regular expression for a string that will act as the name, where the minimum number of characters accepted is 5 and the maximum is 30.
Best Practice #2: MIN/MAX/PATTERN in Parameters
For parameters inside the operations, we must have the same care we have with the schema, see the following code snippet:
Code Definition
@RequestMapping(method = RequestMethod.PATCH, path="/person/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
ā¦
public void updateEmail(
@ApiParam(required=true, value="Id of the person to be updated. Cannot be empty.") @PathVariable @Min(10) @Max(50) int id,
@ApiParam(required=true, value="New Email - Cannot be empty.") @RequestParam @Min(10) @Max(50) @Pattern(regexp= Constants.EMAIL_REGEX) String email)
{
personService.getPersonById(id).setEmail(email);
}
Swagger 2.0 Equivalent
"parameters": [
{
"name": "email",
"in": "query",
"description": "New Email - Cannot be empty.",
"required": true,
"type": "string",
"maxLength": 50,
"minLength": 10,
"pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$",
"allowEmptyValue": false
},
{
"name": "id",
"in": "path",
"description": "Id of the person to be updated. Cannot be empty.",
"required": true,
"type": "integer",
"maximum": 50,
"exclusiveMaximum": false,
"minimum": 10,
"exclusiveMinimum": false,
"format": "int32"
}
The code snippet above prevents an attribute that expects an email address to receive a potential attack trying to use part of the valid domain, or even other tricks to violate this information. At the same time, the ID parameter is fully protected, working with values in the ranges and formats described in the generated OAS (Swagger) file.
Best Practice #3: ENSURES ALL ERROR CODES HAVE A CORRESPONDING SCHEMA
All error codes must have a corresponding error structure, described by a schema (this ensures we can validate payloads for requests/responses).
Depending on the verb used (GET, POST, PUT, etc.), we recommend supporting specificĀ HTTP codes such as 401, 403, 404, or 415. Please see the code snippet below:Ā
Code Definition
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successful operation", response = SuccessfulMessage.class),
@ApiResponse(code = 401, message = "Requires Authentication", response = ErrorMessage.class),
@ApiResponse(code = 403, message = "Not Authorized", response = ErrorMessage.class),
@ApiResponse(code = 404, message = "User Not Found", response = ErrorMessage.class),
@ApiResponse(code = 415, message = "Content type not supported.", response = ErrorMessage.class)})
Swagger 2.0 Equivalent
"responses": {
"200": {
"description": "Successful operation",
"schema": {
"$ref": "#/definitions/SuccessfulMessage"
}
},
"401": {
"description": "Requires Authentication",
"schema": {
"$ref": "#/definitions/ErrorMessage"
}
},
"403": {
"description": "Not Authorized",
"schema": {
"$ref": "#/definitions/ErrorMessage"
}
},
"404": {
"description": "User Not Found",
"schema": {
"$ref": "#/definitions/ErrorMessage"
}
},
"415": {
"description": "Content type not supported.",
"schema": {
"$ref": "#/definitions/ErrorMessage"
}
}
Conclusion
Spring Boot is a widely used framework to produce APIs and Microservices, together with Springfox, both can deliver an impressive OAS (Swagger) file in terms of data validation at the same time that you can get your APIs fully protected. In order to get insightful recommendations to get better OAS (Swagger) files, please consider using our extensions for the main IDEs in the market (VS Code, IntelliJ, and Eclipse), as well as our extensions/plugins for the CI/CD (Jenkins, Gitlab, GitHub, Azure Pipelines, etc). Keep in mind that: The more secure OAS (Swagger) files are, the more secure your APIs will be.
42Crunch IDE and CI/CD Extensions: https://42crunch.com/free-tools/