Skip to content

Commit 0054370

Browse files
committed
fix: reject inverted TrafficProtectionPolicy paranoia levels
A TrafficProtectionPolicy whose blocking paranoia level exceeds its detection paranoia level is an illegal OWASP CRS configuration. CRS rule 901500 fails closed and denies every request at phase 1 with HTTP 500 before any attack evaluation, so a misconfigured policy silently 500s 100% of traffic to the protected route. Because blocking and detection were validated independently (each 1..4, default 1), setting blocking: 2 while leaving detection at its default 1 was admissible. Add a CEL admission rule on ParanoiaLevels requiring detection >= blocking so the illegal combination is rejected at write time. Key changes: - add XValidation rule "self.detection >= self.blocking" on ParanoiaLevels - regenerate CRD and API reference docs - add e2e regression asserting admission rejects blocking > detection
1 parent e159acf commit 0054370

4 files changed

Lines changed: 98 additions & 0 deletions

File tree

api/v1alpha/trafficprotectionpolicy_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ type OWASPCRS struct {
110110
RuleExclusions *OWASPRuleExclusions `json:"ruleExclusions,omitempty"`
111111
}
112112

113+
// +kubebuilder:validation:XValidation:message="detection paranoia level must be greater than or equal to blocking paranoia level",rule="self.detection >= self.blocking"
113114
type ParanoiaLevels struct {
114115
// Blocking specifies the paranoia level for blocking requests or responses.
115116
//

config/crd/bases/networking.datumapis.com_trafficprotectionpolicies.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ spec:
8989
minimum: 1
9090
type: integer
9191
type: object
92+
x-kubernetes-validations:
93+
- message: detection paranoia level must be greater than
94+
or equal to blocking paranoia level
95+
rule: self.detection >= self.blocking
9296
ruleExclusions:
9397
description: |-
9498
RuleExclusions can be used to disable specific OWASP ModSecurity Rules.

docs/api/trafficprotectionpolicies.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ Core Rule Set (CRS).
191191
ParanoiaLevels specifies the OWASP ModSecurity Core Rule Set (CRS)
192192
paranoia levels to use.<br/>
193193
<br/>
194+
<i>Validations</i>:<li>self.detection >= self.blocking: detection paranoia level must be greater than or equal to blocking paranoia level</li>
194195
<i>Default</i>: map[]<br/>
195196
</td>
196197
<td>false</td>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
2+
apiVersion: chainsaw.kyverno.io/v1alpha1
3+
kind: Test
4+
metadata:
5+
name: trafficprotectionpolicy-paranoia-validation
6+
# Regression for issue #250: a TrafficProtectionPolicy whose blocking paranoia
7+
# level exceeds its detection paranoia level is an illegal CRS configuration
8+
# (CRS rule 901500 denies every request with HTTP 500). The CRD now carries a
9+
# CEL rule requiring detection >= blocking, so the illegal combination must be
10+
# rejected at admission rather than silently 500ing all traffic.
11+
spec:
12+
cluster: nso-standard
13+
steps:
14+
- name: Reject blocking > detection at admission
15+
try:
16+
- apply:
17+
expect:
18+
- check:
19+
($error != null): true
20+
resource:
21+
apiVersion: networking.datumapis.com/v1alpha
22+
kind: TrafficProtectionPolicy
23+
metadata:
24+
name: inverted-paranoia
25+
spec:
26+
mode: Enforce
27+
targetRefs:
28+
- group: gateway.networking.k8s.io
29+
kind: Gateway
30+
name: waf-gw
31+
ruleSets:
32+
- type: OWASPCoreRuleSet
33+
owaspCoreRuleSet:
34+
paranoiaLevels:
35+
blocking: 2
36+
detection: 1
37+
38+
- name: Reject blocking set with detection defaulted at admission
39+
try:
40+
- apply:
41+
expect:
42+
- check:
43+
($error != null): true
44+
resource:
45+
apiVersion: networking.datumapis.com/v1alpha
46+
kind: TrafficProtectionPolicy
47+
metadata:
48+
name: default-detection-paranoia
49+
spec:
50+
mode: Enforce
51+
targetRefs:
52+
- group: gateway.networking.k8s.io
53+
kind: Gateway
54+
name: waf-gw
55+
ruleSets:
56+
- type: OWASPCoreRuleSet
57+
owaspCoreRuleSet:
58+
paranoiaLevels:
59+
blocking: 2
60+
61+
- name: Accept detection >= blocking
62+
try:
63+
- apply:
64+
resource:
65+
apiVersion: networking.datumapis.com/v1alpha
66+
kind: TrafficProtectionPolicy
67+
metadata:
68+
name: valid-paranoia
69+
spec:
70+
mode: Enforce
71+
targetRefs:
72+
- group: gateway.networking.k8s.io
73+
kind: Gateway
74+
name: waf-gw
75+
ruleSets:
76+
- type: OWASPCoreRuleSet
77+
owaspCoreRuleSet:
78+
paranoiaLevels:
79+
blocking: 2
80+
detection: 3
81+
catch:
82+
- delete:
83+
ref:
84+
apiVersion: networking.datumapis.com/v1alpha
85+
kind: TrafficProtectionPolicy
86+
name: valid-paranoia
87+
finally:
88+
- delete:
89+
ref:
90+
apiVersion: networking.datumapis.com/v1alpha
91+
kind: TrafficProtectionPolicy
92+
name: valid-paranoia

0 commit comments

Comments
 (0)