Authors:
@lornajane
Lorna Mitchell (Redocly)
A ruleset to pick up on some common API mistakes using linting. A security mindset means more than a few linting rules - but we hope that they help!
Included in this set are a few defensive data type rules, plus a few others from the OWASP recommendations:
rule/no-http-basic
- Don't use HTTP Basic authrule/operation-security
- Security must be defined at the operation levelrule/https-server-urls
- Server URLs must use httpsrule/limit-string-length
- Avoid overflow errors by setting a maximum length for string valuesrule/limit-array-length
- Avoid overflow errors by setting a maximum number of array items
What else should be here? Open an issue - or a pull request.
The following code snippet shows the rules to use:
rules:
rule/no-http-basic:
message: HTTP Basic should not be used.
subject:
type: SecurityRequirement
property: scheme
assertions:
notPattern: /basic/i
where:
- subject:
type: SecurityRequirement
assertions:
defined: true
severity: error
rule/operation-security:
message: Security must be defined at the operation level.
subject:
type: Operation
property: security
assertions:
defined: true
severity: warn
rule/https-server-urls:
message: Server URLs must start with "https:".
subject:
type: Server
property: url
assertions:
pattern: /^https:/
severity: error
rule/limit-string-length:
message: Strings must have maxLength defined, or be an enum/const
subject:
type: Schema
assertions:
requireAny:
- maxLength
- enum
- const
where:
- subject:
type: Schema
property: type
assertions:
const: string
defined: true
severity: warn
rule/limit-array-length:
message: Arrays must have a maxItems property
subject:
type: Schema
assertions:
required:
- maxItems
where:
- subject:
type: Schema
property: type
assertions:
const: array
defined: true
severity: warn
You can copy and paste this configuration into your own redocly.yaml
file, and adjust the severity
settings to suit your use case.
Then run redocly lint
to apply the linting rules to your API description.
Each rule has its own example. Run redocly lint openapi.yaml
to lint your API description.
This rule picks up where a security scheme uses a scheme of "Basic" (or "basic"). Avoid using an example like the following:
components:
securitySchemes:
LegacyAuth:
type: http
scheme: basic
It is recommended to use a scheme such as bearer or digest in your APIs.
OpenAPI allows security to be defined at the top level of the document, but this rule adds a check that every endpoint has a security definition. By intentionally securing each endpoint with an appropriate configuration, security mistakes are less likely to occur.
Each operation should look like the example below:
operationId: getMuseumHours
security:
summary: Get museum hours
- ReaderAuth
description: Get upcoming museum operating hours.
This approach also makes it easier to use tighter security for endpoints with side effects.
It is good practice to use HTTPS endpoints to protect any credentials or important information during transit.
This rule identifies any plain http://
URLs in the server array, such as the following example:
servers:
- url: "http://example.com/museum-api/"
Correct this problem by using https://
URLs for all endpoints.
To avoid API endpoints receiving payloads that could cause overflow errors, set limits on the size of the fields that can be accepted or define specific values that can be sent.
All of the following field examples are acceptable:
components:
schemas:
TicketType:
description: Type of ticket being purchased. Use `general` for regular museum entry and `event` for tickets to special events.
type: string
enum:
- event
- general
example: event
Delivery:
description: The method of ticket delivery for the purchased ticket.
type: string
const: Digital
Email:
description: Email address for ticket purchaser.
type: string
format: email
maxLength: 120
example: [email protected]
Note that the const
keyword came in with the updated JSON Schema version in OpenAPI 3.1.
For OpenAPI 3.0, use an enum
field with a single option.
Similar to the previous point about setting a maximum string field size, set a realistic limit for the size of the arrays that your endpoints accept. By setting a maximum array size to a sensible limit, you can avoid having your API endpoints try to process something so large that they cause problems.
The following example shows an array field with a limit set:
EventDates:
type: array
maxItems: 4
items:
$ref: "#/components/schemas/Date"
description: List of planned dates for the special event.
Pick a limit that's generous for the size of the data that you expect, but small enough that it can be handled without performance implications.
- OWASP top ten
- Published linting rulesets from Spectral and Vacuum