From 0e2b099be537a2cc4f1b73e3407c53d094458fae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 22:55:26 +0000 Subject: [PATCH 1/2] Initial plan From 4848b9f9b815d545ff3000568929f35aa8b71ad4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:03:01 +0000 Subject: [PATCH 2/2] test: add more coverage for raw argument collections Co-authored-by: fzipi <3012076+fzipi@users.noreply.github.com> --- go.sum | 2 - internal/bodyprocessors/multipart_test.go | 40 +++++++ internal/bodyprocessors/urlencoded_test.go | 60 ++++++++++ internal/corazawaf/transaction_test.go | 123 +++++++++++++++++++++ internal/url/url_test.go | 80 ++++++++++++++ testing/coreruleset/go.mod | 2 +- testing/coreruleset/go.sum | 4 +- testing/engine/args_raw.go | 85 ++++++++++++++ 8 files changed, 391 insertions(+), 5 deletions(-) diff --git a/go.sum b/go.sum index 6286aac04..6f81a85ee 100644 --- a/go.sum +++ b/go.sum @@ -75,8 +75,6 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/internal/bodyprocessors/multipart_test.go b/internal/bodyprocessors/multipart_test.go index 97b9b63b1..d3608cbb5 100644 --- a/internal/bodyprocessors/multipart_test.go +++ b/internal/bodyprocessors/multipart_test.go @@ -330,3 +330,43 @@ text defa`) t.Fatalf("expected ArgsPost 'text' to be 'text defa', got %q", textValues[0]) } } + +func TestMultipartArgsPostRaw(t *testing.T) { + // For multipart, field values are not URL-encoded, so ArgsPostRaw should equal ArgsPost. + payload := strings.TrimSpace(` +-----------------------------9051914041544843365972754266 +Content-Disposition: form-data; name="username" + +john_doe +-----------------------------9051914041544843365972754266 +Content-Disposition: form-data; name="comment" + +hello world +-----------------------------9051914041544843365972754266-- +`) + + mp := multipartProcessor(t) + v := corazawaf.NewTransactionVariables() + if err := mp.ProcessRequest(strings.NewReader(payload), v, plugintypes.BodyProcessorOptions{ + Mime: "multipart/form-data; boundary=---------------------------9051914041544843365972754266", + }); err != nil { + t.Fatal(err) + } + + // ArgsPost and ArgsPostRaw should both contain the field values (raw == cooked for multipart). + argsPost := v.ArgsPost() + argsPostRaw := v.ArgsPostRaw() + + fields := map[string]string{ + "username": "john_doe", + "comment": "hello world", + } + for field, want := range fields { + if got := argsPost.Get(field); len(got) == 0 || got[0] != want { + t.Errorf("ArgsPost[%q]: got %v, want %q", field, got, want) + } + if got := argsPostRaw.Get(field); len(got) == 0 || got[0] != want { + t.Errorf("ArgsPostRaw[%q]: got %v, want %q", field, got, want) + } + } +} diff --git a/internal/bodyprocessors/urlencoded_test.go b/internal/bodyprocessors/urlencoded_test.go index c9912483a..d0059d248 100644 --- a/internal/bodyprocessors/urlencoded_test.go +++ b/internal/bodyprocessors/urlencoded_test.go @@ -13,6 +13,66 @@ import ( "github.com/corazawaf/coraza/v3/internal/corazawaf" ) +func TestURLEncodeRawValues(t *testing.T) { + bp, err := bodyprocessors.GetBodyProcessor("urlencoded") + if err != nil { + t.Fatal(err) + } + + tests := []struct { + name string + body string + wantCooked map[string]string // decoded value in ArgsPost + wantRaw map[string]string // raw value in ArgsPostRaw + }{ + { + name: "percent-encoded value", + body: "key=%3Cscript%3E", + wantCooked: map[string]string{"key": "