From 35dfd1f5e04de201465d4f28d26ceb9d75bfcf97 Mon Sep 17 00:00:00 2001 From: sneak Date: Mon, 9 Nov 2026 20:59:45 +0000 Subject: [PATCH 1/2] Core Rule Set: test concurrent requests keep their own exclusions A Drupal and a WordPress request are inspected at once, many times over, on one Core Rule Set. Coraza v3.8.1 shares each rule's exclusions between requests, so the test fails under -race. Model: opus-5-5 --- internal/coreruleset/coreruleset_test.go | 37 ++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/internal/coreruleset/coreruleset_test.go b/internal/coreruleset/coreruleset_test.go index bfdf50a..f695303 100644 --- a/internal/coreruleset/coreruleset_test.go +++ b/internal/coreruleset/coreruleset_test.go @@ -13,6 +13,7 @@ import ( "slices" "strconv" "strings" + "sync" "testing" "sneak.berlin/go/smallwebwaf/internal/coreruleset" @@ -39,6 +40,42 @@ func newCoreRuleSet(t *testing.T, level int, disabled ...int) *coreruleset.CoreR return crs } +// TestConcurrentRequestsKeepTheirOwnExclusions inspects a Drupal and a +// WordPress request at once, many times over, on one Core Rule Set, as +// sww's server does. Each passes only while its own exclusions apply. +func TestConcurrentRequestsKeepTheirOwnExclusions(t *testing.T) { + t.Parallel() + + const rounds = 50 + + crs := atDefaults(t) + targets := []string{ + "/admin/people?user=docker-compose.yml&status=All&role=All&permission=All", + "/wp-admin/edit-tags.php?taxonomy=post_tag&post_type=post&s=python3", + } + + var inspecting sync.WaitGroup + + for range rounds { + for _, target := range targets { + inspecting.Go(func() { + req := httptest.NewRequestWithContext(t.Context(), http.MethodGet, + "http://git.example"+target, nil) + req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:131.0) "+ + "Gecko/20100101 Firefox/131.0") + req.Header.Set("Accept", "text/html") + + result, _, err := crs.Inspect(req, netip.MustParseAddr("203.0.113.9"), req.Body) + if err != nil || !reflect.DeepEqual(result, coreruleset.Result{}) { + t.Errorf("GET %s: %+v, %v", target, result, err) + } + }) + } + } + + inspecting.Wait() +} + // request is a request a test inspects: its method, its target, the path // and the query as a client sends them, and its headers, each written // "Name: value". -- 2.54.0 From c0313f7b27445b519f35dc113e0557bd14fa325f Mon Sep 17 00:00:00 2001 From: sneak Date: Mon, 9 Nov 2026 21:00:08 +0000 Subject: [PATCH 2/2] Coraza: use the commit that keeps exclusions per request (closes #254) Coraza v3.8.1 shares a rule's ctl:ruleRemoveTargetById exclusions between concurrent requests, so one request can be checked with another's. Coraza's main fixed it in its pull request 1745; no release carries it yet, so go.mod names commit d028be399c68 by its pseudo-version. Model: opus-5-5 --- go.mod | 8 ++++---- go.sum | 22 ++++++++++++---------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 5470c26..6f7510b 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.26.0 require ( github.com/corazawaf/coraza-coreruleset/v4 v4.25.0 - github.com/corazawaf/coraza/v3 v3.8.1 + github.com/corazawaf/coraza/v3 v3.8.2-0.20261022102553-d028be399c68 github.com/fsnotify/fsnotify v1.10.1 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/maxmind/mmdbwriter v1.2.0 @@ -15,7 +15,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/corazawaf/libinjection-go v0.3.3 // indirect + github.com/corazawaf/libinjection-go v0.3.4 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/goccy/go-yaml v1.19.2 // indirect github.com/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976 // indirect @@ -34,10 +34,10 @@ require ( github.com/tidwall/pretty v1.2.1 // indirect github.com/valllabh/ocsf-schema-golang v1.0.3 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/net v0.58.0 // indirect + golang.org/x/net v0.60.0 // indirect golang.org/x/sync v0.23.0 // indirect golang.org/x/sys v0.48.0 // indirect - golang.org/x/text v0.41.0 // indirect + golang.org/x/text v0.42.0 // indirect google.golang.org/protobuf v1.36.11 // indirect rsc.io/binaryregexp v0.2.0 // indirect ) diff --git a/go.sum b/go.sum index 58f2e8b..9abff90 100644 --- a/go.sum +++ b/go.sum @@ -2,14 +2,16 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/corazawaf/coraza-coreruleset v0.0.0-20240226094324-415b1017abdc h1:OlJhrgI3I+FLUCTI3JJW8MoqyM78WbqJjecqMnqG+wc= -github.com/corazawaf/coraza-coreruleset v0.0.0-20240226094324-415b1017abdc/go.mod h1:7rsocqNDkTCira5T0M7buoKR2ehh7YZiPkzxRuAgvVU= +github.com/corazawaf/coraza-coreruleset/crs/tests/v4 v4.30.0 h1:ZX0xWXpQgRXV/4sdfw21mOZBmmzQSb1+JiR51YOLv8I= +github.com/corazawaf/coraza-coreruleset/crs/tests/v4 v4.30.0/go.mod h1:yf3Gc7mGKBR1wchr4EXZHG10En6WQ4W4MJCg3ix91wQ= +github.com/corazawaf/coraza-coreruleset/crs/v4 v4.30.0 h1:XMYT7VOFM2VrpIKMUn4vFWyoFNYg1ZaYiexs76AmxzQ= +github.com/corazawaf/coraza-coreruleset/crs/v4 v4.30.0/go.mod h1:1yaQUjecpEJ/cWXhJaFto+vRuezJCCfVxGQlaQxAGt0= github.com/corazawaf/coraza-coreruleset/v4 v4.25.0 h1:tqFO1lfVpTiyWtlN618OXpZMfw+nnN0Q4///W5W+/HM= github.com/corazawaf/coraza-coreruleset/v4 v4.25.0/go.mod h1:nRuGXITxOPvsLF2VxaTB7pYok8QB8BitX3ZenXcUryY= -github.com/corazawaf/coraza/v3 v3.8.1 h1:dMV55FbMR2vOks/acrT43RShR+VkzU6jwp+XPdxay8o= -github.com/corazawaf/coraza/v3 v3.8.1/go.mod h1:nPVk2JqADYBcKLYvo9cRsr+z4JhanU0WniGhZZBZD6c= -github.com/corazawaf/libinjection-go v0.3.3 h1:NhbXKRfRpqKzBMzv8zpCcnjyEw7BCVhBOv9IPuBl7Fc= -github.com/corazawaf/libinjection-go v0.3.3/go.mod h1:Ik/+w3UmTWH9yn366RgS9D95K3y7Atb5m/H/gXzzPCk= +github.com/corazawaf/coraza/v3 v3.8.2-0.20261022102553-d028be399c68 h1:KLEjvBBSwQcxvgT6h1VDjRLtQ+V9eObAwubb1CTWf9U= +github.com/corazawaf/coraza/v3 v3.8.2-0.20261022102553-d028be399c68/go.mod h1:9XocblQEwK6EYylRth7PrPIifF2l0iSoYo4FAXhXU/8= +github.com/corazawaf/libinjection-go v0.3.4 h1:jX2Tit2xZxYJJyVryNXucYBZtQqS7473x9Nc6lgRRbk= +github.com/corazawaf/libinjection-go v0.3.4/go.mod h1:Ik/+w3UmTWH9yn366RgS9D95K3y7Atb5m/H/gXzzPCk= github.com/foxcpp/go-mockdns v1.2.0 h1:omK3OrHRD1IWJz1FuFBCFquhXslXoF17OvBS6JPzZF0= github.com/foxcpp/go-mockdns v1.2.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= @@ -79,14 +81,14 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c= golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o= -golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= -golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= -golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= golang.org/x/tools v0.50.0 h1:c2ifzfcuY7L90lZ2aKd8S4K2NpASF08SZx9ZuJkHmSU= golang.org/x/tools v0.50.0/go.mod h1:7ulVMw3831Mwi5EZD6RomGyffr4VFjuNYXf2BbCEAV0= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -- 2.54.0