-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspectral-ruleset.yaml
More file actions
110 lines (101 loc) · 4.65 KB
/
Copy pathspectral-ruleset.yaml
File metadata and controls
110 lines (101 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
extends: spectral:oas
functionsDir: ./functions
functions:
- replacementEndpointExists
- outboundCallSecretWhenSigned
- redirectAllowedDomainsRequiresUrl
- accountLockoutIdentifierShape
- nonceCacheRequiresHeader
- urlParamNeedsSsrfPolicy
rules:
x-security-x-security-valid:
description: x-security block must validate against the x-security JSON Schema
message: "{{error}}"
severity: error
given: "$.paths[*][get,post,put,patch,delete,head,options].x-security"
then:
function: schema
functionOptions:
schema:
$ref: "./src/x-security.schema.json"
x-security-no-unprotected-mutations:
description: Mutating endpoints (POST/PUT/PATCH/DELETE) must declare authentication
severity: error
given: "$.paths[*][post,put,patch,delete]"
then:
field: "x-security.authentication"
function: truthy
x-security-rate-limit-on-auth-endpoints:
description: Authentication endpoints should declare rate limits
severity: warn
given: "$.paths[?(@property.match(/login|signin|auth|token/i))][post]"
then:
field: "x-security.rateLimit"
function: truthy
x-security-no-wildcard-cors-with-credentials:
description: CORS wildcard origin with credentials is insecure
severity: error
given: "$.paths[*][*].x-security.cors"
then:
function: falsy
functionOptions:
# Evaluated by JSON Schema `not` rule in x-security.schema.json
property: "_invalid_wildcard_credentials"
# v0.4 S-7: replacementEndpoint must resolve to a path declared in the same
# OpenAPI document. Implemented as a custom function (functions/replacementEndpointExists.js)
# because Spectral built-ins can't cross-reference $.paths from a leaf JSONPath.
xsec-replacement-endpoint-exists:
description: x-security.replacementEndpoint must reference a path declared in this OpenAPI document
documentationUrl: https://usewaf.com/docs/rules/xsec-replacement-endpoint-exists
message: "{{error}}"
severity: warn
given: "$.paths[*][get,post,put,patch,delete,head,options].x-security.replacementEndpoint"
then:
function: replacementEndpointExists
# v0.5 S-11: outboundCalls signed-without-secret check.
xsec-outbound-call-secret-set-when-signed:
description: outboundCalls entries declaring a signatureAlgorithm other than 'none' must also declare secretRef
documentationUrl: https://usewaf.com/docs/rules/xsec-outbound-call-secret
message: "{{error}}"
severity: error
given: "$.paths[*][get,post,put,patch,delete,head,options].x-security.outboundCalls"
then:
function: outboundCallSecretWhenSigned
# W10-9: url-typed params must declare SSRF defense (domainAllowlist OR
# blockPrivateRanges). Severity warn — operators may legitimately omit on
# internal-only endpoints, but the missing policy needs to be visible.
xsec-url-param-needs-ssrf-policy:
description: request.schema params with type=url should declare domainAllowlist or blockPrivateRanges
documentationUrl: https://usewaf.com/docs/rules/xsec-url-param-needs-ssrf-policy
message: "{{error}}"
severity: warn
given: "$.paths[*][get,post,put,patch,delete,head,options].x-security.request"
then:
function: urlParamNeedsSsrfPolicy
# v0.5 S-15: redirectAllowedDomains only meaningful on type:'url' params.
xsec-redirect-allowed-domains-with-url-type:
description: request.schema.*.redirectAllowedDomains only applies when the param type is 'url'
documentationUrl: https://usewaf.com/docs/rules/xsec-redirect-allowed-domains
message: "{{error}}"
severity: warn
given: "$.paths[*][get,post,put,patch,delete,head,options].x-security.request"
then:
function: redirectAllowedDomainsRequiresUrl
# v0.5 S-12: account-lockout identifier shape sanity check.
xsec-account-lockout-identifier-shape:
description: accountLockout.identifier should reference a per-user key (header:X-Username, request.body.email, ...), not 'ip'
documentationUrl: https://usewaf.com/docs/rules/xsec-account-lockout-identifier
message: "{{error}}"
severity: warn
given: "$.paths[*][get,post,put,patch,delete,head,options].x-security.authentication.accountLockout"
then:
function: accountLockoutIdentifierShape
# v0.5 S-17: nonceCacheTtl requires nonceHeader.
xsec-nonce-cache-requires-header:
description: request.signature.nonceCacheTtl is meaningless without nonceHeader
documentationUrl: https://usewaf.com/docs/rules/xsec-nonce-cache-requires-header
message: "{{error}}"
severity: error
given: "$.paths[*][get,post,put,patch,delete,head,options].x-security.request.signature"
then:
function: nonceCacheRequiresHeader