'Security' field of the operation is not defined
Issue ID: v3-operation-security
Average severity: Critical
Description
The security
field of the operation has not been defined. This field specifies if your API operation requires the API consumer to authenticate to use it.
For more details, see the OpenAPI Specification.
Example
The security
field is tightly coupled with the securitySchemes
objects. The security
field could be missing because:
- You forgot to define the
securitySchemes
field altogether, leaving the API completely unprotected. - You defined the
securitySchemes
field but not thesecurity
field. The definitions are not actually getting applied. - You defined the
securitySchemes
field and the operation-levelsecurity
field for some of the API operations. However, you did not define thesecurity
field on the global level for the whole API.
Possible exploit scenario
If you do not set the global security
field, the API does not require any authentication by default. Anyone can use the API operations that do not have a security
field defined. All they need to know is the URL for the API operation and how to invoke it.
This sometimes happens to internal APIs. These are often created only to be used inside the company web pages and mobile applications. No one expects any outsiders to know that the API exists, so developers do not spend time implementing security.
But attackers can look at the code of the mobile or web application, or listen to the API traffic, and reverse engineer how the API works. Once the attackers have figured this out, they can start using the API because it does not require any authentication.
Relying on defining security
only on each operation individually is an error-prone approach. It is very easy to forget to set security
when you add a new method to the API. If there is no global default security
defined, the operation is left wide open for an attacker to invoke without any authentication required.
Remediation
First, define the securitySchemes
object on the global level, and list the authentication methods that you plan to use. For example:
{
"components": {
"securitySchemes": {
"OAuth2": {
"type": "oauth2",
"flows": {
"authorizationCode": {
"scopes": {
"readOnly": "read objects in your account"
},
"authorizationUrl": "https://example.com/oauth/authorize",
"tokenUrl": "https://example.com/oauth/token"
}
}
},
"apiKey": {
"type": "apiKey",
"name": "X-API-Key",
"in": "cookie"
}
}
}
}
Then, use the security
field on the global level to set the default authentication requirements for the whole API.
If you have more than one definition in securitySchemes
and you want to apply all of them for each API call, use the following syntax (semantically AND):
{
"security": [
{ "OAuth2": ["readOnly"], "apiKey": [] }
]
}
If you want to apply only one of the definitions to an API call, use the following syntax (semantically OR):
{
"security": [
{ "OAuth2": ["readOnly"] },
{ "apiKey": [] }
]
}
You can add an exception to the security specified on the global level on the operation level as needed. This overrides the authentication requirements of the whole API. Simply add a separate security
field to the operation in question.