API Security Checklist: Part 3
This is the final blog in the series outlining 15 best practices for strengthening API security with a shift-left approach. If you haven’t had a chance to read the API Security Checklist: Secure API Design (first) and API Security Checklist: Part 2 (second) article in this series, now is a good time.
In the first blog, we discuss how objects should have data types defined, how APIs should have authorization schemes implemented, and that the communication between the client and server should use secure transport mechanisms. The second blog discusses the restrictions that need to be placed on the data exchanged between the client and the server, specifically for string objects.
This blog extends that conversation by outlining the restrictions on other data types.
Ready? Let’s go.
Five Final Ways To Make APIs More Secure
For those who still haven’t had a chance to look at the previous articles in this series, here is some preliminary information for what we are about to discuss: the best practices to mitigate security risks in your API specifications. These best practices can be enforced using the CloudVector static risk assessment tool. The tool analyzes a Swagger specification to look for vulnerabilities/design issues across 30+ pre-defined checks. In addition to identifying what the issue is, the tool also points to where the issue occurs within the specification and the impact that entails. The tool also labels every identified issue with a corresponding severity (Critical/High/Medium/Low) and categorizes the issue as belonging to a Security, Data, or Format category. We note the severity and category for every issue (a.k.a best practice) discussed in this series.
Onto the best practices now…
Issue #11: Integer objects should have a format defined.
cvtags: Severity-Medium, Category-Data
What: Here, the format field is required to be specified whenever the object (could either be a parameter or an element of an array) is of the type integer. The format field itself can take different values depending upon the data type in question. For integer values though, the format needs to be one of int32 or int64. We show an example of a specified format string in Figure 1.
Impact: Absence of the appropriate format may require the application to consume 64-bit integers where only 32-bit were expected. This can result in either unexpected application behavior or the application crash resulting in a Denial of Service. Specifying the format is also a good practice from the perspective of database management. Correct format helps allocate appropriate resources for hosting data.
Remediation: Specify the format for integer objects as one of int32 or int64.
Issue #12: Integer objects should have a minimum/maximum defined.
cvtags: Severity-Medium, Category-Data
What: Following up on the theme where sanity of input/output data should be maintained: this issue highlights the need to confine the range of values accepted by an integer object. Integer objects support the maximum and minimum fields (as shown in Figure 2). The violation occurs when either of these fields are absent.
Impact: In the example shown in Figure 2, the parameter amount can have a value between 0 and 1000. Absence of such a range could challenge the business logic as in the example above where a transaction amount of more than a $1k can indicate violation of the seller’s financial directives or allow the attacker to misuse the vulnerability for perpetrating fraud.
Remediation: The API developer should specify the strictest minimum and maximum values as per the business requirements.
Issue #13: Response codes should be between 100 and 599 (inclusive)
cvtags: Severity-Medium, Category-Format
What: Note that this type of violation belongs to the Format category.
Within the API specification, every API typically outlines the response behavior within the responses object. Each behavior is specific to the HTTP response code returned. For instance, the API may return a number of user records when the response status code is 200 while it only returns the problem string when any application error occurs (response code 5xx). Below is an example of an unexpected response code.
Impact: Responding to a client request with an unexpected response status code can cause client application to crash. Moreover, it can create developer confusion since such status codes are not part of protocol standards.
Remediation: Specify the response status code between 100-500.
Issue #14: SecurityDefinitions is absent or empty.
cvtags: Severity-Critical, Category-Security
What: The securityDefinitions field helps identify the scopes and security schemes that may apply to individual API operations. For example, the fact that the API should use an API key or the OAuth2 scheme for authorized access, is dictated within the securityDefinitions object. Therefore, an absent or empty object implies no authorization mechanisms used.
Figure 4 shows an example specification where the field securityDefinitions is present but empty.
Impact: As mentioned above, lack of authorization mechanisms allows free access to an organization’s assets which is generally a bad idea.
Remediation: Every API should specify a security scheme (using the security field) and the definitions of the used security schemes should be captured clearly in the global securityDefinitions object.
Issue #15: Security scope not present in securityDefinitions.
cvtags: Severity-High, Category-Security
What: The previous issue highlights the motivation to define and use authorization scopes. This issue, specifically, stems from using a scope which has not been defined. Figure 5 explains more.
As evident in the figure, the scope delete:cust used by the API /products is not present within the scopes defined for the security scheme acme:auth.
Impact: Misinterpreting the security scope that should not have been implemented in the first place, allows an attacker the authorization to manipulate the target organization’s assets in a nefarious manner.
Remediation: Use only the scopes as defined in the global securityDefinitions field.
Earlier we mentioned how the best practices described in this blog series can be enforced using the CloudVector Risk Assessment tool. The tool, in addition to identifying the score, severity, and category for every discovered violation, also integrates with the business’ CI/CD pipelines. To elaborate, the tool can be configured to trigger exit codes on specific criteria such as the discovery of specific (or higher) severity. The triggered exit codes can subsequently be fed to version control or build pipelines to prohibit a vulnerable specification from making it into production.
In addition to the best practices identified by CloudVector, the risk assessment tool also has the unique ability for the user to specify their own custom rules using a flexible rule-specification language. Custom rules help an organization integrate their own best practices in addition to the CloudVector rules and can also be leveraged with the tool’s CI/CD integration ability to significantly bolster the API security posture.
Lastly, since the output of the tool is JSON based, it also allows the users to develop their own analytics around how the API specifications are evolving over time. These insights are in addition to the insights that the tool itself provides. If you would like to know more about the tool and its capabilities, please reach out to email@example.com.
Through the first, second, and this article, we have highlighted 15 best practices that should be applied to OpenAPI specifications. Failure to implement such best practices exposes the application to security risks such as data theft, asset misappropriation, denial of service, or more. The enforcement of such API design principles can also be enforced using tools which check for violations of the identified best practices discussed in this blog series.
The CloudVector risk assessment tool helps enforce such best practices and also provides the ability to define customized rules making it flexible for individual organizations to enforce their own best practices. This is achieved through a flexible rule definition language. The enforcement ability integrates with CI/CD pipelines so that insecure designs never make it to the next stage.