diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2216d6b05..9bcbfb7e9 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Initialize CodeQL - uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3 + uses: github/codeql-action/init@5f8171a638ada777af81d42b55959a643bb29017 # v3 with: languages: go - name: Autobuild - uses: github/codeql-action/autobuild@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3 + uses: github/codeql-action/autobuild@5f8171a638ada777af81d42b55959a643bb29017 # v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3 + uses: github/codeql-action/analyze@5f8171a638ada777af81d42b55959a643bb29017 # v3 diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index f143fd35d..f61c056e6 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5 + - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5 with: go-version: ">=1.23.0" - run: go run mage.go fuzz diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1ffdccb7f..ddcf2f354 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,8 +20,8 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install Go - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5 + uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5 with: - go-version: v1.23.x + go-version: 1.24.x cache: true - run: go run mage.go lint diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index adf5916af..c78c9aa2b 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -42,7 +42,7 @@ jobs: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install Go - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5 + uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5 with: go-version: ${{ matrix.go-version }} cache: true @@ -51,28 +51,28 @@ jobs: export BUILD_TAGS=${{ matrix.build-flag }} go run mage.go coverage - name: "Codecov: General" - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5 if: ${{ matrix.go-version == env.GOLANG_BASE_VERSION }} with: files: build/coverage.txt flags: default,${{ matrix.build-flag }} token: ${{ secrets.CODECOV_TOKEN }} - name: "Codecov: Examples" - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5 if: ${{ matrix.go-version == env.GOLANG_BASE_VERSION }} with: files: build/coverage-examples.txt flags: examples+${{ matrix.build-flag }} token: ${{ secrets.CODECOV_TOKEN }} - name: "Codecov: FTW" - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5 if: ${{ matrix.go-version == env.GOLANG_BASE_VERSION }} with: files: build/coverage-ftw.txt flags: ftw,${{ matrix.build-flag }} token: ${{ secrets.CODECOV_TOKEN }} - name: "Codecov: Tinygo" - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5 + uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5 # only if coverage-tinygo.txt exists if: ${{ matrix.go-version == env.GOLANG_BASE_VERSION && hashFiles('build/coverage-tinygo.txt') != '' }} with: diff --git a/.github/workflows/tinygo.yml b/.github/workflows/tinygo.yml index 90f6b4dba..7ac8f13a6 100644 --- a/.github/workflows/tinygo.yml +++ b/.github/workflows/tinygo.yml @@ -27,7 +27,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install Go - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5 + uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5 with: go-version: ${{ matrix.go-version }} cache: true @@ -38,7 +38,7 @@ jobs: tinygo-version: ${{ matrix.tinygo-version }} - name: Cache TinyGo build - uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4 + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4 with: path: | ~/.cache/tinygo diff --git a/examples/http-server/go.mod b/examples/http-server/go.mod index 480fd7b57..51fc92c82 100644 --- a/examples/http-server/go.mod +++ b/examples/http-server/go.mod @@ -1,6 +1,6 @@ module github.com/corazawaf/coraza/v3/examples/http-server -go 1.22.0 +go 1.23.0 require github.com/corazawaf/coraza/v3 v3.2.1 @@ -11,8 +11,8 @@ require ( github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sync v0.10.0 // indirect + golang.org/x/net v0.37.0 // indirect + golang.org/x/sync v0.12.0 // indirect golang.org/x/tools v0.22.0 // indirect rsc.io/binaryregexp v0.2.0 // indirect ) diff --git a/examples/http-server/go.sum b/examples/http-server/go.sum index 05299a64f..254fbc686 100644 --- a/examples/http-server/go.sum +++ b/examples/http-server/go.sum @@ -19,12 +19,12 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= diff --git a/experimental/plugins/plugintypes/auditlog.go b/experimental/plugins/plugintypes/auditlog.go index 4742953fb..787402a2d 100644 --- a/experimental/plugins/plugintypes/auditlog.go +++ b/experimental/plugins/plugintypes/auditlog.go @@ -81,6 +81,7 @@ type AuditLogMessage interface { Actionset() string Message() string Data() AuditLogMessageData + // TODO(4.x): Add Log() ErrorMessage() string } // AuditLogMessageData contains information about the triggered rules diff --git a/go.mod b/go.mod index 89afc2991..27cda75f4 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/corazawaf/coraza/v3 -go 1.23.6 +go 1.23.0 // Testing dependencies: // - go-mockdns @@ -23,12 +23,12 @@ require ( github.com/foxcpp/go-mockdns v1.1.0 github.com/jcchavezs/mergefs v0.1.0 github.com/magefile/mage v1.15.1-0.20241126214340-bdc92f694516 - github.com/mccutchen/go-httpbin/v2 v2.16.0 + github.com/mccutchen/go-httpbin/v2 v2.18.0 github.com/petar-dambovaliev/aho-corasick v0.0.0-20240411101913-e07a1f0e8eb4 github.com/tidwall/gjson v1.18.0 github.com/valllabh/ocsf-schema-golang v1.0.3 - golang.org/x/net v0.35.0 - golang.org/x/sync v0.11.0 + golang.org/x/net v0.37.0 + golang.org/x/sync v0.12.0 rsc.io/binaryregexp v0.2.0 ) @@ -40,9 +40,9 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect golang.org/x/mod v0.18.0 // indirect - golang.org/x/sys v0.30.0 // indirect + golang.org/x/sys v0.31.0 // indirect golang.org/x/tools v0.22.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.35.1 // indirect ) retract v3.2.2 diff --git a/go.sum b/go.sum index 89d5a14aa..f807f3e88 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,10 @@ github.com/jcchavezs/mergefs v0.1.0 h1:7oteO7Ocl/fnfFMkoVLJxTveCjrsd//UB0j89xmnp github.com/jcchavezs/mergefs v0.1.0/go.mod h1:eRLTrsA+vFwQZ48hj8p8gki/5v9C2bFtHH5Mnn4bcGk= github.com/magefile/mage v1.15.1-0.20241126214340-bdc92f694516 h1:aAO0L0ulox6m/CLRYvJff+jWXYYCKGpEm3os7dM/Z+M= github.com/magefile/mage v1.15.1-0.20241126214340-bdc92f694516/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/mccutchen/go-httpbin/v2 v2.16.0 h1:dzoFvE4fWPIzWZ7ZRznLDYK9FpqXyx5NE3uzCngeTHM= -github.com/mccutchen/go-httpbin/v2 v2.16.0/go.mod h1:GBy5I7XwZ4ZLhT3hcq39I4ikwN9x4QUt6EAxNiR8Jus= +github.com/mccutchen/go-httpbin/v2 v2.17.1 h1:35FQXl1KT4CcJV6O5RtUc91tdMIBMzaJWW5+ZLA8CxY= +github.com/mccutchen/go-httpbin/v2 v2.17.1/go.mod h1:GBy5I7XwZ4ZLhT3hcq39I4ikwN9x4QUt6EAxNiR8Jus= +github.com/mccutchen/go-httpbin/v2 v2.18.0 h1:WFU1OELp3nHYLvXct/3nrGVIgxU0X+RJfDPYRBnvicY= +github.com/mccutchen/go-httpbin/v2 v2.18.0/go.mod h1:GBy5I7XwZ4ZLhT3hcq39I4ikwN9x4QUt6EAxNiR8Jus= github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/petar-dambovaliev/aho-corasick v0.0.0-20240411101913-e07a1f0e8eb4 h1:1Kw2vDBXmjop+LclnzCb/fFy+sgb3gYARwfmoUcQe6o= @@ -53,16 +55,16 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -73,8 +75,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -98,8 +100,8 @@ golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= diff --git a/go.work b/go.work index 21c5ac83f..f58734883 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.23.6 +go 1.23.0 use ( . diff --git a/internal/auditlog/auditlog.go b/internal/auditlog/auditlog.go index 7a0383b7d..d75c27cd2 100644 --- a/internal/auditlog/auditlog.go +++ b/internal/auditlog/auditlog.go @@ -363,9 +363,10 @@ func (trf TransactionRequestFiles) Mime() string { // Message contains information about the triggered // rules type Message struct { - Actionset_ string `json:"actionset"` - Message_ string `json:"message"` - Data_ *MessageData `json:"data"` + Actionset_ string `json:"actionset"` + Message_ string `json:"message"` + ErrorMessage_ string `json:"error_message"` + Data_ *MessageData `json:"data"` } var _ plugintypes.AuditLogMessage = Message{} @@ -378,6 +379,10 @@ func (m Message) Message() string { return m.Message_ } +func (m Message) ErrorMessage() string { + return m.ErrorMessage_ +} + func (m Message) Data() plugintypes.AuditLogMessageData { return m.Data_ } diff --git a/internal/auditlog/formats.go b/internal/auditlog/formats.go index dab2c91c4..316566927 100644 --- a/internal/auditlog/formats.go +++ b/internal/auditlog/formats.go @@ -30,6 +30,8 @@ import ( type nativeFormatter struct{} +type auditLogWithErrMesg interface{ ErrorMessage() string } + func (nativeFormatter) Format(al plugintypes.AuditLog) ([]byte, error) { if len(al.Parts()) == 0 { return nil, nil @@ -100,11 +102,21 @@ func (nativeFormatter) Format(al plugintypes.AuditLog) ([]byte, error) { // Producer: ModSecurity for Apache/2.9.1 (http://www.modsecurity.org/). // Server: Apache // Engine-Mode: "ENABLED" + + // AuditLogTrailer is also expected to contain the error message generated by the rule, if any + for _, alEntry := range al.Messages() { + alWithErrMsg, ok := alEntry.(auditLogWithErrMesg) + if ok && alWithErrMsg.ErrorMessage() != "" { + res.WriteByte('\n') + res.WriteString(alWithErrMsg.ErrorMessage()) + } + } + _, _ = fmt.Fprintf(&res, "\nStopwatch: %s\nResponse-Body-Transformed: %s\nProducer: %s\nServer: %s", "", "", "", "") case types.AuditLogPartRulesMatched: - for _, r := range al.Messages() { + for _, alEntry := range al.Messages() { res.WriteByte('\n') - res.WriteString(r.Data().Raw()) + res.WriteString(alEntry.Data().Raw()) } } res.WriteByte('\n') diff --git a/internal/auditlog/formats_test.go b/internal/auditlog/formats_test.go index 91381aad4..759f3f7eb 100644 --- a/internal/auditlog/formats_test.go +++ b/internal/auditlog/formats_test.go @@ -78,12 +78,13 @@ func TestNativeFormatter(t *testing.T) { checkLine(t, lines, 10, mutateSeparator(separator, 'F')) checkLine(t, lines, 12, "some: response header") checkLine(t, lines, 13, mutateSeparator(separator, 'H')) - checkLine(t, lines, 15, "Stopwatch: ") - checkLine(t, lines, 16, "Response-Body-Transformed: ") - checkLine(t, lines, 17, "Producer: ") - checkLine(t, lines, 18, "Server: ") - checkLine(t, lines, 19, mutateSeparator(separator, 'K')) - checkLine(t, lines, 21, `SecAction "id:100"`) + checkLine(t, lines, 15, "error message") + checkLine(t, lines, 16, "Stopwatch: ") + checkLine(t, lines, 17, "Response-Body-Transformed: ") + checkLine(t, lines, 18, "Producer: ") + checkLine(t, lines, 19, "Server: ") + checkLine(t, lines, 20, mutateSeparator(separator, 'K')) + checkLine(t, lines, 22, `SecAction "id:100"`) }) } @@ -128,7 +129,8 @@ func createAuditLog() *Log { }, Messages_: []plugintypes.AuditLogMessage{ &Message{ - Message_: "some message", + Message_: "some message", + ErrorMessage_: "error message", Data_: &MessageData{ Msg_: "some message", Raw_: "SecAction \"id:100\"", diff --git a/internal/corazawaf/transaction.go b/internal/corazawaf/transaction.go index 8264c7e67..c17baa933 100644 --- a/internal/corazawaf/transaction.go +++ b/internal/corazawaf/transaction.go @@ -765,7 +765,7 @@ func (tx *Transaction) ProcessURI(uri string, method string, httpVersion string) uri = uri[:in] } path := "" - parsedURL, err := url.Parse(uri) + parsedURL, err := url.ParseRequestURI(uri) query := "" if err != nil { tx.variables.urlencodedError.Set(err.Error()) @@ -1434,6 +1434,7 @@ func (tx *Transaction) AuditLog() *auditlog.Log { IsInterrupted_: tx.IsInterrupted(), } + var auditLogPartAuditLogTrailerSet, auditLogPartRulesMatchedSet bool for _, part := range tx.AuditLogParts { switch part { case types.AuditLogPartRequestHeaders: @@ -1486,6 +1487,7 @@ func (tx *Transaction) AuditLog() *auditlog.Log { al.Transaction_.Response_.Status_ = status al.Transaction_.Response_.Headers_ = tx.variables.responseHeaders.Data() case types.AuditLogPartAuditLogTrailer: + auditLogPartAuditLogTrailerSet = true al.Transaction_.Producer_ = &auditlog.TransactionProducer{ Connector_: tx.WAF.ProducerConnector, Version_: tx.WAF.ProducerConnectorVersion, @@ -1495,6 +1497,7 @@ func (tx *Transaction) AuditLog() *auditlog.Log { Rulesets_: tx.WAF.ComponentNames, } case types.AuditLogPartRulesMatched: + auditLogPartRulesMatchedSet = true for _, mr := range tx.matchedRules { // Log action is required to log a matched rule on both error log and audit log // An assertion has to be done to check if the MatchedRule implements the Log() function before calling Log() @@ -1503,7 +1506,7 @@ func (tx *Transaction) AuditLog() *auditlog.Log { if ok && mrWithlog.Log() { r := mr.Rule() for _, matchData := range mr.MatchedDatas() { - al.Messages_ = append(al.Messages_, auditlog.Message{ + newAlEntry := auditlog.Message{ Actionset_: strings.Join(tx.WAF.ComponentNames, " "), Message_: matchData.Message(), Data_: &auditlog.MessageData{ @@ -1520,13 +1523,33 @@ func (tx *Transaction) AuditLog() *auditlog.Log { Tags_: r.Tags(), Raw_: r.Raw(), }, - }) + } + // If AuditLogPartAuditLogTrailer (H) is set, we expect to log the error messages emitted by the rules + // in the audit log + if auditLogPartAuditLogTrailerSet { + newAlEntry.ErrorMessage_ = mr.ErrorLog() + } + al.Messages_ = append(al.Messages_, newAlEntry) } } } } } + // If AuditLogPartRulesMatched (K) is not set, but AuditLogPartAuditLogTrailer (H) is set, we still expect to + // log the error messages emitted by the rules (if the rule has Log set to true) + if !auditLogPartRulesMatchedSet && auditLogPartAuditLogTrailerSet { + for _, mr := range tx.matchedRules { + mrWithlog, ok := mr.(*corazarules.MatchedRule) + if ok && mrWithlog.Log() { + al.Messages_ = append(al.Messages_, auditlog.Message{ + ErrorMessage_: mr.ErrorLog(), + }) + } + } + + } + return al } diff --git a/internal/corazawaf/transaction_test.go b/internal/corazawaf/transaction_test.go index 979aa608b..50b0c8477 100644 --- a/internal/corazawaf/transaction_test.go +++ b/internal/corazawaf/transaction_test.go @@ -7,6 +7,7 @@ import ( "bytes" "fmt" "io" + "net/http" "regexp" "runtime/debug" "strconv" @@ -1787,3 +1788,78 @@ func TestCloseFails(t *testing.T) { t.Fatalf("unexpected error message: %s", err.Error()) } } + +func TestRequestFilename(t *testing.T) { + tests := []struct { + name string + uri string + expected string + }{ + { + name: "simple", + uri: "/foo", + expected: "/foo", + }, + { + name: "with query", + uri: "/foo?bar=baz", + expected: "/foo", + }, + { + name: "with query and fragment", + uri: "/foo?bar=baz#qux", + expected: "/foo", + }, + { + name: "subdirectory", + uri: "/foo/bar", + expected: "/foo/bar", + }, + { + name: "subdirectory with query", + uri: "/foo/bar?baz=qux", + expected: "/foo/bar", + }, + { + name: "multiple leading slashes", + uri: "//foo/bar", + expected: "//foo/bar", + }, + { + name: "multiple leading slashes - 2", + uri: "///foo/bar", + expected: "///foo/bar", + }, + { // This is a bug. This test should be adapted when the issue is fixed. + name: "invalid encoding", + uri: "/foo%zz?a=b", + expected: "/foo%zz?a=b", + }, + { + name: "valid encoding", + uri: "/foo%20bar", + expected: "/foo bar", + }, + { + name: "trailing slash", + uri: "/foo/bar/", + expected: "/foo/bar/", + }, + { + name: "duplicated slashes", + uri: "//foo//bar", + expected: "//foo//bar", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + waf := NewWAF() + tx := waf.NewTransaction() + tx.ProcessURI(test.uri, http.MethodGet, "HTTP/1.1") + if tx.variables.requestFilename.Get() != test.expected { + t.Fatalf("Expected REQUEST_FILENAME %q, got %q", test.expected, tx.variables.requestFilename.Get()) + } + }) + } +} diff --git a/internal/transformations/hex_decode.go b/internal/transformations/hex_decode.go index 3e0aff391..0caa8eb19 100644 --- a/internal/transformations/hex_decode.go +++ b/internal/transformations/hex_decode.go @@ -1,3 +1,6 @@ +// Copyright 2025 Juan Pablo Tosso and the OWASP Coraza contributors +// SPDX-License-Identifier: Apache-2.0 + package transformations import ( diff --git a/internal/transformations/hex_decode_test.go b/internal/transformations/hex_decode_test.go index 9b145968b..14e7f3115 100644 --- a/internal/transformations/hex_decode_test.go +++ b/internal/transformations/hex_decode_test.go @@ -1,3 +1,6 @@ +// Copyright 2025 Juan Pablo Tosso and the OWASP Coraza contributors +// SPDX-License-Identifier: Apache-2.0 + package transformations import ( diff --git a/magefile.go b/magefile.go index c47242479..524f44d32 100644 --- a/magefile.go +++ b/magefile.go @@ -23,7 +23,7 @@ import ( var addLicenseVersion = "v1.1.1" // https://github.com/google/addlicense/releases var gosImportsVer = "v0.3.7" // https://github.com/rinchsan/gosimports/releases -var golangCILintVer = "v1.60.3" // https://github.com/golangci/golangci-lint/releases +var golangCILintVer = "v1.64.8" // https://github.com/golangci/golangci-lint/releases var errNoGitDir = errors.New("no .git directory found") var errUpdateGeneratedFiles = errors.New("generated files need to be updated") diff --git a/testing/auditlog_test.go b/testing/auditlog_test.go index fdbfb2c5c..5985a0553 100644 --- a/testing/auditlog_test.go +++ b/testing/auditlog_test.go @@ -183,7 +183,7 @@ func TestAuditLogRelevantOnlyNoAuditlog(t *testing.T) { } } -func TestAuditLogOnNoLog(t *testing.T) { +func TestAuditLogOnWithNoLog(t *testing.T) { waf := corazawaf.NewWAF() parser := seclang.NewParser(waf) if err := parser.FromString(` @@ -194,7 +194,7 @@ func TestAuditLogOnNoLog(t *testing.T) { SecAuditLogParts ABCHIJKZ SecAuditLogRelevantStatus ".*" # auditlog tells that the transaction will have to log matches meant to be logged (not the ones with nolog) - SecRule ARGS "@unconditionalMatch" "id:1,phase:1,nolog,auditlog,msg:'nolog message'" + SecRule ARGS "@unconditionalMatch" "id:1,phase:1,nolog,msg:'nolog message'" `); err != nil { t.Fatal(err) } @@ -333,3 +333,105 @@ func TestAuditLogRequestBody(t *testing.T) { t.Fatalf("Expected %s uri, got %s", params, req.Body()) } } + +// Arule expected to be logged (log and auditlog flags enabled) should +// print the error message in the audit log as part of the H section. +func TestAuditLogHFlag(t *testing.T) { + waf := corazawaf.NewWAF() + parser := seclang.NewParser(waf) + if err := parser.FromString(` + SecRuleEngine DetectionOnly + SecAuditEngine On + SecAuditLogFormat json + SecAuditLogType serial + SecAuditLogParts AHZ + SecAuditLogRelevantStatus ".*" + # An audit log should contain messages section on H flag included + SecRule ARGS "@unconditionalMatch" "id:1,phase:1,log,auditlog,msg:'expected rule message'" + `); err != nil { + t.Fatal(err) + } + // generate a random tmp file + file, err := os.Create(filepath.Join(t.TempDir(), "tmp.log")) + if err != nil { + t.Fatal(err) + } + defer os.Remove(file.Name()) + if err := parser.FromString(fmt.Sprintf("SecAuditLog %s", file.Name())); err != nil { + t.Fatal(err) + } + tx := waf.NewTransaction() + tx.AddGetRequestArgument("test", "test") + tx.ProcessRequestHeaders() + // now we read file + if _, err := file.Seek(0, 0); err != nil { + t.Error(err) + } + tx.ProcessLogging() + var al auditlog.Log + if err := json.NewDecoder(file).Decode(&al); err != nil { + t.Error(err) + } + if len(al.Messages()) != 1 { + t.Fatalf("Expected 1 message, got %d", len(al.Messages())) + } + type auditLogWithErrMesg interface{ ErrorMessage() string } + alWithErrMsg, ok := al.Messages()[0].(auditLogWithErrMesg) + if !ok { + t.Fatalf("Expected message to be of type auditLogWithErrMesg") + } + expected := "expected rule message" + if !strings.Contains(alWithErrMsg.ErrorMessage(), expected) { + t.Errorf("Expected audit log to contain %q, got %q", expected, alWithErrMsg.ErrorMessage()) + } +} + +func TestAuditLogWithKFlagWithoutHFlag(t *testing.T) { + waf := corazawaf.NewWAF() + parser := seclang.NewParser(waf) + if err := parser.FromString(` + SecRuleEngine DetectionOnly + SecAuditEngine On + SecAuditLogFormat json + SecAuditLogType serial + SecAuditLogParts ABCKZ + SecAuditLogRelevantStatus ".*" + # auditlog should not contain error logs without H flag included + SecRule ARGS "@unconditionalMatch" "id:1,phase:1,log,auditlog,msg:'unexpected logged message'" + `); err != nil { + t.Fatal(err) + } + // generate a random tmp file + file, err := os.Create(filepath.Join(t.TempDir(), "tmp.log")) + if err != nil { + t.Fatal(err) + } + defer os.Remove(file.Name()) + if err := parser.FromString(fmt.Sprintf("SecAuditLog %s", file.Name())); err != nil { + t.Fatal(err) + } + tx := waf.NewTransaction() + tx.AddGetRequestArgument("test", "test") + tx.ProcessRequestHeaders() + // now we read file + if _, err := file.Seek(0, 0); err != nil { + t.Error(err) + } + tx.ProcessLogging() + var al auditlog.Log + if err := json.NewDecoder(file).Decode(&al); err != nil { + t.Error(err) + } + if len(al.Messages()) != 1 { + t.Fatalf("Expected 1 message, got %d", len(al.Messages())) + } + type auditLogWithErrMesg interface{ ErrorMessage() string } + alWithErrMsg, ok := al.Messages()[0].(auditLogWithErrMesg) + if !ok { + t.Fatalf("Expected message to be of type auditLogWithErrMesg") + } + notExpected := "unexpected logged message" + if strings.Contains(alWithErrMsg.ErrorMessage(), notExpected) { + t.Errorf("Not expected audit log to contain %q, got %q", notExpected, alWithErrMsg.ErrorMessage()) + } +} diff --git a/testing/coreruleset/go.mod b/testing/coreruleset/go.mod index 21e16864a..d983006e1 100644 --- a/testing/coreruleset/go.mod +++ b/testing/coreruleset/go.mod @@ -1,16 +1,14 @@ module github.com/corazawaf/coraza/v3/testing/coreruleset -go 1.22.3 - -toolchain go1.23.6 +go 1.23.0 require ( github.com/bmatcuk/doublestar/v4 v4.8.1 github.com/corazawaf/coraza-coreruleset/v4 v4.7.0 - github.com/corazawaf/coraza/v3 v3.3.2 - github.com/coreruleset/albedo v0.0.16 + github.com/corazawaf/coraza/v3 v3.3.3 + github.com/coreruleset/albedo v0.1.0 github.com/coreruleset/go-ftw v1.3.0 - github.com/rs/zerolog v1.33.0 + github.com/rs/zerolog v1.34.0 ) require ( @@ -21,6 +19,7 @@ require ( github.com/coreruleset/ftw-tests-schema/v2 v2.2.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/icza/backscanner v0.0.0-20241124160932-dff01ac50250 // indirect @@ -44,10 +43,10 @@ require ( github.com/tidwall/pretty v1.2.1 // indirect github.com/valllabh/ocsf-schema-golang v1.0.3 // indirect github.com/yargevad/filepathx v1.0.0 // indirect - golang.org/x/crypto v0.33.0 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.37.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect golang.org/x/time v0.9.0 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/testing/coreruleset/go.sum b/testing/coreruleset/go.sum index 618a93897..4a44f0079 100644 --- a/testing/coreruleset/go.sum +++ b/testing/coreruleset/go.sum @@ -4,8 +4,6 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/bmatcuk/doublestar/v4 v4.8.0 h1:DSXtrypQddoug1459viM9X9D3dp1Z7993fw36I2kNcQ= -github.com/bmatcuk/doublestar/v4 v4.8.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38= github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/corazawaf/coraza-coreruleset v0.0.0-20240226094324-415b1017abdc h1:OlJhrgI3I+FLUCTI3JJW8MoqyM78WbqJjecqMnqG+wc= @@ -17,10 +15,10 @@ github.com/corazawaf/libinjection-go v0.2.2/go.mod h1:OP4TM7xdJ2skyXqNX1AN1wN5nN github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreruleset/albedo v0.0.16 h1:YYWEJBSfAwVmZ5tbBgQQhL8uU6IKeA2QwpAkii3UPKY= github.com/coreruleset/albedo v0.0.16/go.mod h1:6mYBASfvvRM2ckXgYO7N5nyKAj8OqLnT4+YLbM0/XWE= +github.com/coreruleset/albedo v0.1.0 h1:W3vNOWYgj8Ug6+KpqsAjM+osk1uW1ruoNCmMc9o1YLE= +github.com/coreruleset/albedo v0.1.0/go.mod h1:t3ZNKLVHzxzGll+Ddzgcw5FFIdiYNobTfcNdKvQHpkc= github.com/coreruleset/ftw-tests-schema/v2 v2.2.0 h1:G2NA/XMOWSIvRqVDt/9NlqrVF+Qhz3Ngys8JOfb5plc= github.com/coreruleset/ftw-tests-schema/v2 v2.2.0/go.mod h1:QEkxQti2T54tDWFPocxgAtLhw6J+zXV44JkqGFFP0is= -github.com/coreruleset/go-ftw v1.2.0 h1:/z7BCJPgmL/wdXYOSTgKYeHUcKyHvJzxmr1c8l1zcvA= -github.com/coreruleset/go-ftw v1.2.0/go.mod h1:OnCo0SQjzKH17pxvTUB7MUY8jCENVP/FWpfSYGZVIU8= github.com/coreruleset/go-ftw v1.3.0 h1:PqjiODI3oDqANP+eUlx8WIY67fPs75Ey1muZviC4o9Y= github.com/coreruleset/go-ftw v1.3.0/go.mod h1:Mzi9R4i2wFvTlkS+jXorqzmwcDSLSrNNUv5KasEa+C0= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -86,8 +84,11 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= @@ -101,35 +102,23 @@ github.com/valllabh/ocsf-schema-golang v1.0.3 h1:eR8k/3jP/OOqB8LRCtdJ4U+vlgd/gk5 github.com/valllabh/ocsf-schema-golang v1.0.3/go.mod h1:sZ3as9xqm1SSK5feFWIR2CuGeGRhsM7TR1MbpBctzPk= github.com/yargevad/filepathx v1.0.0 h1:SYcT+N3tYGi+NvazubCNlvgIPbzAk7i7y2dwg3I5FYc= github.com/yargevad/filepathx v1.0.0/go.mod h1:BprfX/gpYNJHJfc35GjRRpVcwWXS89gGulUIU5tK3tA= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= -golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/types/rule_match.go b/types/rule_match.go index a45e332af..3fb2297e6 100644 --- a/types/rule_match.go +++ b/types/rule_match.go @@ -47,4 +47,6 @@ type MatchedRule interface { AuditLog() string ErrorLog() string + + // TODO(4.x): Add Log() }