# Comprehensive OWASP API Security Top 10 2023 Spectral Ruleset # This ruleset enforces OWASP API Security best practices for OpenAPI specifications extends: ["spectral:oas"] rules: # ============================================================================ # API1:2023 - Broken Object Level Authorization # ============================================================================ operation-security-defined: description: All operations must have security requirements defined (OWASP API1) severity: error given: $.paths[*][get,post,put,patch,delete,head] then: - field: security function: truthy message: "Operations must define security requirements to prevent unauthorized object access (OWASP API1:2023 - Broken Object Level Authorization)" id-parameters-require-security: description: Operations with ID parameters must have security defined severity: error given: $.paths[?(@property =~ /(\/\{id\}|\/\{.*[_-]id\})/i)][get,put,patch,delete] then: - field: security function: truthy message: "Operations with ID parameters require security to prevent IDOR vulnerabilities (OWASP API1:2023)" # ============================================================================ # API2:2023 - Broken Authentication # ============================================================================ security-schemes-required: description: API must define security schemes (OWASP API2) severity: error given: $.components then: - field: securitySchemes function: truthy message: "API must define security schemes to prevent authentication bypass (OWASP API2:2023 - Broken Authentication)" no-http-basic-auth: description: HTTP Basic authentication is insecure for APIs severity: error given: $.components.securitySchemes[*] then: - field: scheme function: pattern functionOptions: notMatch: "^basic$" message: "HTTP Basic authentication transmits credentials in plain text - use OAuth2, API key, or JWT (OWASP API2:2023)" bearer-format-specified: description: Bearer authentication should specify token format (JWT recommended) severity: warn given: $.components.securitySchemes[?(@.type == 'http' && @.scheme == 'bearer')] then: - field: bearerFormat function: truthy message: "Bearer authentication should specify token format (bearerFormat: JWT) for clarity (OWASP API2:2023)" # ============================================================================ # API3:2023 - Broken Object Property Level Authorization # ============================================================================ no-additional-properties: description: Prevent mass assignment by disabling additionalProperties severity: warn given: $.components.schemas[?(@.type == 'object')] then: - field: additionalProperties function: falsy message: "Set additionalProperties to false to prevent mass assignment vulnerabilities (OWASP API3:2023 - Broken Object Property Level Authorization)" schemas-have-properties: description: Object schemas should explicitly define properties severity: warn given: $.components.schemas[?(@.type == 'object')] then: - field: properties function: truthy message: "Explicitly define object properties to control data exposure (OWASP API3:2023)" # ============================================================================ # API4:2023 - Unrestricted Resource Consumption # ============================================================================ rate-limit-headers-documented: description: API should document rate limiting headers severity: warn given: $.paths[*][get,post,put,patch,delete].responses[?(@property < '300')].headers then: function: schema functionOptions: schema: type: object anyOf: - required: [X-RateLimit-Limit] - required: [X-Rate-Limit-Limit] - required: [RateLimit-Limit] message: "Document rate limiting headers to communicate resource consumption limits (OWASP API4:2023 - Unrestricted Resource Consumption)" pagination-parameters-present: description: List operations should support pagination severity: warn given: $.paths[*].get then: - field: parameters function: schema functionOptions: schema: type: array contains: anyOf: - properties: name: enum: [limit, per_page, page_size] - properties: name: enum: [offset, page, cursor] message: "List operations should support pagination (limit/offset or cursor) to prevent resource exhaustion (OWASP API4:2023)" # ============================================================================ # API5:2023 - Broken Function Level Authorization # ============================================================================ write-operations-require-security: description: Write operations must have security requirements severity: error given: $.paths[*][post,put,patch,delete] then: - field: security function: truthy message: "Write operations must have security requirements to prevent unauthorized function access (OWASP API5:2023 - Broken Function Level Authorization)" admin-paths-require-security: description: Admin endpoints must have strict security severity: error given: $.paths[?(@property =~ /admin/i)][*] then: - field: security function: truthy message: "Admin endpoints require security requirements with appropriate scopes (OWASP API5:2023)" # ============================================================================ # API7:2023 - Server Side Request Forgery # ============================================================================ no-url-parameters: description: Avoid URL parameters to prevent SSRF attacks severity: warn given: $.paths[*][*].parameters[?(@.in == 'query' || @.in == 'body')][?(@.name =~ /(url|uri|link|callback|redirect|webhook)/i)] then: function: truthy message: "URL parameters can enable SSRF attacks - validate and whitelist destination URLs (OWASP API7:2023 - Server Side Request Forgery)" # ============================================================================ # API8:2023 - Security Misconfiguration # ============================================================================ servers-use-https: description: All API servers must use HTTPS severity: error given: $.servers[*].url then: function: pattern functionOptions: match: "^https://" message: "Server URLs must use HTTPS protocol for secure communication (OWASP API8:2023 - Security Misconfiguration)" no-example-servers: description: Replace example server URLs with actual endpoints severity: error given: $.servers[*].url then: function: pattern functionOptions: notMatch: "example\\.com" message: "Replace example.com with actual production server URLs (OWASP API8:2023)" security-headers-in-responses: description: Document security headers in responses severity: info given: $.paths[*][*].responses[*].headers then: function: schema functionOptions: schema: type: object anyOf: - required: [X-Content-Type-Options] - required: [X-Frame-Options] - required: [Strict-Transport-Security] - required: [Content-Security-Policy] message: "Consider documenting security headers (X-Content-Type-Options, X-Frame-Options, HSTS, CSP) (OWASP API8:2023)" # ============================================================================ # API9:2023 - Improper Inventory Management # ============================================================================ api-version-required: description: API specification must include version severity: error given: $.info then: - field: version function: truthy message: "API version must be specified for proper inventory management (OWASP API9:2023 - Improper Inventory Management)" semantic-versioning-format: description: Use semantic versioning for API versions severity: warn given: $.info.version then: function: pattern functionOptions: match: "^\\d+\\.\\d+(\\.\\d+)?$" message: "Use semantic versioning format (MAJOR.MINOR.PATCH) for API versions (OWASP API9:2023)" contact-info-required: description: API must include contact information severity: warn given: $.info then: - field: contact function: truthy message: "Include contact information for API support and security reporting (OWASP API9:2023)" deprecated-endpoints-documented: description: Deprecated endpoints must document migration path severity: warn given: $.paths[*][*][?(@.deprecated == true)] then: - field: description function: pattern functionOptions: match: "(deprecate|migrate|alternative|replacement|use instead)" message: "Deprecated endpoints must document migration path and timeline (OWASP API9:2023)" # ============================================================================ # API10:2023 - Unsafe Consumption of APIs # ============================================================================ validate-external-api-responses: description: Document validation of external API responses severity: info given: $.paths[*][*].responses[*].content[*].schema then: - field: description function: truthy message: "Document schema validation for all API responses, especially from external APIs (OWASP API10:2023 - Unsafe Consumption of APIs)" # ============================================================================ # Additional Security Best Practices # ============================================================================ no-pii-in-query-parameters: description: Prevent PII exposure in URL query parameters severity: error given: $.paths[*][*].parameters[?(@.in == 'query')].name then: function: pattern functionOptions: notMatch: "(?i)(ssn|social.?security|credit.?card|password|secret|token|api.?key|private|passport|driver.?license)" message: "Query parameters must not contain PII or sensitive data - use request body with HTTPS instead" consistent-error-response-format: description: Error responses should follow consistent format severity: warn given: $.paths[*][*].responses[?(@property >= '400')].content.application/json.schema then: function: schema functionOptions: schema: type: object required: [error, message] message: "Error responses should follow consistent format with 'error' and 'message' fields" no-verbose-error-details: description: 5xx errors should not expose internal details severity: warn given: $.paths[*][*].responses[?(@property >= '500')].content[*].schema.properties then: function: schema functionOptions: schema: type: object not: anyOf: - required: [stack_trace] - required: [stackTrace] - required: [debug_info] message: "5xx error responses should not expose stack traces or internal details in production"