@@ -317,6 +317,28 @@ spec:
317317 name: httpbin-service-e2e-test
318318 port:
319319 number: 80
320+ `
321+ ingressCSRF = `
322+ apiVersion: networking.k8s.io/v1
323+ kind: Ingress
324+ metadata:
325+ name: csrf
326+ annotations:
327+ k8s.apisix.apache.org/enable-csrf: "true"
328+ k8s.apisix.apache.org/csrf-key: "foo-key"
329+ spec:
330+ ingressClassName: %s
331+ rules:
332+ - host: httpbin.example
333+ http:
334+ paths:
335+ - path: /anything
336+ pathType: Prefix
337+ backend:
338+ service:
339+ name: httpbin-service-e2e-test
340+ port:
341+ number: 80
320342`
321343 )
322344 BeforeEach (func () {
@@ -359,5 +381,53 @@ spec:
359381 Status (http .StatusPermanentRedirect ).
360382 Header ("Location" ).IsEqual ("/anything/ip" )
361383 })
384+
385+ It ("csrf" , func () {
386+ Expect (s .CreateResourceFromString (fmt .Sprintf (ingressCSRF , s .Namespace ()))).ShouldNot (HaveOccurred (), "creating Ingress" )
387+
388+ time .Sleep (5 * time .Second )
389+
390+ By ("Request without CSRF token should fail" )
391+ msg401 := s .NewAPISIXClient ().
392+ POST ("/anything" ).
393+ WithHeader ("Host" , "httpbin.example" ).
394+ Expect ().
395+ Status (http .StatusUnauthorized ).
396+ Body ().
397+ Raw ()
398+ Expect (msg401 ).To (ContainSubstring ("no csrf token in headers" ), "checking error message" )
399+
400+ By ("GET request should succeed and return CSRF token in cookie" )
401+ resp := s .NewAPISIXClient ().
402+ GET ("/anything" ).
403+ WithHeader ("Host" , "httpbin.example" ).
404+ Expect ().
405+ Status (http .StatusOK )
406+ resp .Header ("Set-Cookie" ).NotEmpty ()
407+
408+ cookie := resp .Cookie ("apisix-csrf-token" )
409+ token := cookie .Value ().Raw ()
410+
411+ By ("POST request with valid CSRF token should succeed" )
412+ _ = s .NewAPISIXClient ().
413+ POST ("/anything" ).
414+ WithHeader ("Host" , "httpbin.example" ).
415+ WithHeader ("apisix-csrf-token" , token ).
416+ WithCookie ("apisix-csrf-token" , token ).
417+ Expect ().
418+ Status (http .StatusOK )
419+
420+ By ("Verify CSRF plugin is configured in the route" )
421+ routes , err := s .DefaultDataplaneResource ().Route ().List (context .Background ())
422+ Expect (err ).NotTo (HaveOccurred (), "listing Route" )
423+ Expect (routes ).To (HaveLen (1 ), "checking Route length" )
424+ Expect (routes [0 ].Plugins ).To (HaveKey ("csrf" ), "checking Route plugins" )
425+ jsonBytes , err := json .Marshal (routes [0 ].Plugins ["csrf" ])
426+ Expect (err ).NotTo (HaveOccurred (), "marshalling csrf plugin config" )
427+ var csrfConfig map [string ]any
428+ err = json .Unmarshal (jsonBytes , & csrfConfig )
429+ Expect (err ).NotTo (HaveOccurred (), "unmarshalling csrf plugin config" )
430+ Expect (csrfConfig ["key" ]).To (Equal ("foo-key" ), "checking csrf key" )
431+ })
362432 })
363433})
0 commit comments