@@ -89,6 +89,34 @@ var testArachniRuleTmpl = template.Must(template.New("").Parse(`
8989}
9090` ))
9191
92+ // Test with a valid JSON but invalid rule format (field "events" should be an array)
93+ const malformedRule = `
94+ {
95+ "version": "2.1",
96+ "events": [
97+ {
98+ "id": "ua0-600-12x",
99+ "name": "Arachni",
100+ "tags": {
101+ "type": "security_scanner"
102+ },
103+ "conditions": [
104+ {
105+ "operation": "match_regex",
106+ "parameters": {
107+ "inputs": [
108+ { "address": "server.request.headers.no_cookies" }
109+ ],
110+ "regex": "^Arachni"
111+ }
112+ }
113+ ],
114+ "transformers": []
115+ }
116+ ]
117+ }
118+ `
119+
92120type ruleInput struct {
93121 Address string
94122 KeyPath []string
@@ -124,43 +152,85 @@ func TestNewWAF(t *testing.T) {
124152 })
125153
126154 t .Run ("invalid-rule" , func (t * testing.T ) {
127- // Test with a valid JSON but invalid rule format (field events should be an array)
128- const rule = `
129- {
130- "version": "2.1",
131- "events": [
132- {
133- "id": "ua0-600-12x",
134- "name": "Arachni",
135- "tags": {
136- "type": "security_scanner"
137- },
138- "conditions": [
139- {
140- "operation": "match_regex",
141- "parameters": {
142- "inputs": [
143- { "address": "server.request.headers.no_cookies" }
144- ],
145- "regex": "^Arachni"
146- }
147- }
148- ],
149- "transformers": []
150- }
151- ]
152- }
153- `
154155 var parsed any
155156
156- require .NoError (t , json .Unmarshal ([]byte (rule ), & parsed ))
157+ require .NoError (t , json .Unmarshal ([]byte (malformedRule ), & parsed ))
157158
158159 waf , err := newDefaultHandle (parsed )
159160 require .Error (t , err )
160161 require .Nil (t , waf )
161162 })
162163}
163164
165+ func TestUpdateWAF (t * testing.T ) {
166+
167+ t .Run ("valid-rule" , func (t * testing.T ) {
168+ waf , err := newDefaultHandle (testArachniRule )
169+ require .NoError (t , err )
170+ require .NotNil (t , waf )
171+ defer waf .Close ()
172+
173+ waf2 , err := waf .Update (newArachniTestRule ([]ruleInput {{Address : "my.input" }}, nil ))
174+ require .NoError (t , err )
175+ require .NotNil (t , waf2 )
176+ defer waf2 .Close ()
177+ })
178+
179+ t .Run ("changes" , func (t * testing.T ) {
180+ waf , err := newDefaultHandle (newArachniTestRule ([]ruleInput {{Address : "my.input" }}, nil ))
181+ require .NoError (t , err )
182+ require .NotNil (t , waf )
183+ defer waf .Close ()
184+
185+ wafCtx := NewContext (waf )
186+ defer wafCtx .Close ()
187+
188+ // Matches
189+ values := map [string ]interface {}{
190+ "my.input" : "Arachni" ,
191+ }
192+ matches , actions , err := wafCtx .Run (values , time .Second )
193+ require .NoError (t , err )
194+ require .NotEmpty (t , matches )
195+ require .Nil (t , actions )
196+
197+ // Update
198+ waf2 , err := waf .Update (newArachniTestRule ([]ruleInput {{Address : "my.input" }}, []string {"block" }))
199+ require .NoError (t , err )
200+ require .NotNil (t , waf2 )
201+ defer waf2 .Close ()
202+
203+ wafCtx2 := NewContext (waf2 )
204+ defer wafCtx2 .Close ()
205+
206+ // Matches & Block
207+ values = map [string ]interface {}{
208+ "my.input" : "Arachni" ,
209+ }
210+ matches , actions , err = wafCtx2 .Run (values , time .Second )
211+ require .NoError (t , err )
212+ require .NotEmpty (t , matches )
213+ require .NotEmpty (t , actions )
214+
215+ })
216+
217+ t .Run ("invalid-rule" , func (t * testing.T ) {
218+
219+ waf , err := newDefaultHandle (testArachniRule )
220+ require .NoError (t , err )
221+ require .NotNil (t , waf )
222+ defer waf .Close ()
223+
224+ var parsed any
225+
226+ require .NoError (t , json .Unmarshal ([]byte (malformedRule ), & parsed ))
227+
228+ waf2 , err := waf .Update (parsed )
229+ require .Error (t , err )
230+ require .Nil (t , waf2 )
231+ })
232+ }
233+
164234func TestMatching (t * testing.T ) {
165235
166236 waf , err := newDefaultHandle (newArachniTestRule ([]ruleInput {{Address : "my.input" }}, nil ))
0 commit comments