From 5aa7f6569e6656890188a8a7034adcb117fabdf9 Mon Sep 17 00:00:00 2001 From: Matteo Pace Date: Thu, 18 Jul 2024 19:55:17 +0200 Subject: [PATCH] feat: Audit logs in proxy-wasm logs (#263) --- go.mod | 2 +- go.sum | 4 +- internal/auditlog/serial_writer.go | 50 +++++++++++++++++++ main.go | 2 + main_test.go | 2 + wasmplugin/rules/coraza-demo.conf | 7 ++- wasmplugin/rules/coraza.conf-recommended.conf | 7 ++- 7 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 internal/auditlog/serial_writer.go diff --git a/go.mod b/go.mod index 741f01b6..046187fb 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/corazawaf/coraza-wasilibs v0.2.0 - github.com/corazawaf/coraza/v3 v3.2.1 + github.com/corazawaf/coraza/v3 v3.2.2-0.20240718151026-8ebb4a82ce41 github.com/stretchr/testify v1.9.0 github.com/tetratelabs/proxy-wasm-go-sdk v0.23.0 github.com/tidwall/gjson v1.17.1 diff --git a/go.sum b/go.sum index d9289c7d..d85467a8 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/corazawaf/coraza-wasilibs v0.2.0 h1:BT8x2pks6Xk7Oi1cUS9BPO+hi3QWQyQAtBkC3IR3Mt8= github.com/corazawaf/coraza-wasilibs v0.2.0/go.mod h1:jmUPQdndtPfMzKPn0a8BqdikXjuT3wY+6zDx5NvKshI= -github.com/corazawaf/coraza/v3 v3.2.1 h1:zBIji4ut9FtFe8lXdqFwXMAkUoDJZ7HsOlEUYWERLI8= -github.com/corazawaf/coraza/v3 v3.2.1/go.mod h1:fVndCGdUHJWl9c26VZPcORQRzUYwMPnRkC6TyTkhbUg= +github.com/corazawaf/coraza/v3 v3.2.2-0.20240718151026-8ebb4a82ce41 h1:BVk6PUP8RsYtSAGlpGH3w0Bnjyjd2nADCy7ZkjXC0MQ= +github.com/corazawaf/coraza/v3 v3.2.2-0.20240718151026-8ebb4a82ce41/go.mod h1:fVndCGdUHJWl9c26VZPcORQRzUYwMPnRkC6TyTkhbUg= github.com/corazawaf/libinjection-go v0.2.1 h1:vNJ7L6c4xkhRgYU6sIO0Tl54TmeCQv/yfxBma30Dy/Y= github.com/corazawaf/libinjection-go v0.2.1/go.mod h1:OP4TM7xdJ2skyXqNX1AN1wN5nNZEmJNuWbNPOItn7aw= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= diff --git a/internal/auditlog/serial_writer.go b/internal/auditlog/serial_writer.go new file mode 100644 index 00000000..54dd7a22 --- /dev/null +++ b/internal/auditlog/serial_writer.go @@ -0,0 +1,50 @@ +// Copyright The OWASP Coraza contributors +// SPDX-License-Identifier: Apache-2.0 + +package auditlog + +import ( + "io" + + "github.com/corazawaf/coraza/v3/experimental/plugins" + "github.com/corazawaf/coraza/v3/experimental/plugins/plugintypes" + "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm" +) + +// RegisterProxyWasmSerialWriter overrides the default "Serial" audit log writer (see https://github.com/corazawaf/coraza/blob/main/internal/auditlog/init_tinygo.go) +// in order to print audit logs to the proxy-wasm log as info messages with a prefix to differentiate them from other logs. +func RegisterProxyWasmSerialWriter() { + plugins.RegisterAuditLogWriter("serial", func() plugintypes.AuditLogWriter { + return &wasmSerial{} + }) +} + +type wasmSerial struct { + io.Closer + formatter plugintypes.AuditLogFormatter +} + +func (s *wasmSerial) Init(cfg plugintypes.AuditLogConfig) error { + s.formatter = cfg.Formatter + return nil +} + +func (s *wasmSerial) Write(al plugintypes.AuditLog) error { + if s.formatter == nil { + return nil + } + + bts, err := s.formatter.Format(al) + if err != nil { + return err + } + + if len(bts) == 0 { + return nil + } + // Print the audit log to the proxy-wasm log as an info message adding an "AuditLog:" prefix. + proxywasm.LogInfo("AuditLog:" + string(bts)) + return nil +} + +func (s *wasmSerial) Close() error { return nil } diff --git a/main.go b/main.go index 1cf03694..9e1fd493 100644 --- a/main.go +++ b/main.go @@ -6,11 +6,13 @@ package main import ( "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm" + "github.com/corazawaf/coraza-proxy-wasm/internal/auditlog" "github.com/corazawaf/coraza-proxy-wasm/internal/operators" "github.com/corazawaf/coraza-proxy-wasm/wasmplugin" ) func main() { operators.Register() + auditlog.RegisterProxyWasmSerialWriter() proxywasm.SetVMContext(wasmplugin.NewVMContext()) } diff --git a/main_test.go b/main_test.go index 5c8ecc98..975a3fc1 100644 --- a/main_test.go +++ b/main_test.go @@ -18,6 +18,7 @@ import ( "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/proxytest" "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types" + "github.com/corazawaf/coraza-proxy-wasm/internal/auditlog" "github.com/corazawaf/coraza-proxy-wasm/wasmplugin" ) @@ -1412,6 +1413,7 @@ func vmTest(t *testing.T, f func(*testing.T, types.VMContext)) { t.Helper() t.Run("go", func(t *testing.T) { + auditlog.RegisterProxyWasmSerialWriter() f(t, wasmplugin.NewVMContext()) }) diff --git a/wasmplugin/rules/coraza-demo.conf b/wasmplugin/rules/coraza-demo.conf index 903027c7..dd810b39 100644 --- a/wasmplugin/rules/coraza-demo.conf +++ b/wasmplugin/rules/coraza-demo.conf @@ -221,7 +221,7 @@ SecDebugLogLevel 3 # trigger a server error (determined by a 5xx or 4xx, excluding 404, # level response status codes). # -SecAuditEngine On +SecAuditEngine RelevantOnly SecAuditLogRelevantStatus "^(?:(5|4)(0|1)[0-9])$" # Log everything we know about a transaction. @@ -230,8 +230,11 @@ SecAuditLogParts ABIJDEFHZ # Use a single file for logging. This is much easier to look at, but # assumes that you will use the audit log only occasionally. # +# Because of proxy-wasm limitations, audit logs can only be written to stdout +# which end up in the proxy logs. SecAuditLogType Serial - +SecAuditLog /dev/stdout +SecAuditLogFormat JSON # -- Miscellaneous ----------------------------------------------------------- diff --git a/wasmplugin/rules/coraza.conf-recommended.conf b/wasmplugin/rules/coraza.conf-recommended.conf index a1c5f967..c8bcd0de 100644 --- a/wasmplugin/rules/coraza.conf-recommended.conf +++ b/wasmplugin/rules/coraza.conf-recommended.conf @@ -220,7 +220,7 @@ SecResponseBodyLimitAction ProcessPartial # trigger a server error (determined by a 5xx or 4xx, excluding 404, # level response status codes). # -SecAuditEngine RelevantOnly +SecAuditEngine Off SecAuditLogRelevantStatus "^(?:(5|4)(0|1)[0-9])$" # Log everything we know about a transaction. @@ -229,8 +229,11 @@ SecAuditLogParts ABIJDEFHZ # Use a single file for logging. This is much easier to look at, but # assumes that you will use the audit log only occasionally. # +# Because of proxy-wasm limitations, audit logs can only be written to stdout +# which end up in the proxy logs. SecAuditLogType Serial - +SecAuditLog /dev/stdout +SecAuditLogFormat JSON # -- Miscellaneous -----------------------------------------------------------