Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Audit logs in proxy-wasm logs #263

Merged
merged 10 commits into from
Jul 18, 2024
1 change: 1 addition & 0 deletions example/envoy/envoy-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ static_resources:
"SecDefaultAction \"phase:3,log,auditlog,pass\"",
"SecDefaultAction \"phase:4,log,auditlog,pass\"",
"SecDefaultAction \"phase:5,log,auditlog,pass\"",
"SecAuditEngine On",
"SecDebugLogLevel 3",
"Include @owasp_crs/*.conf",
"SecRule REQUEST_URI \"@streq /admin\" \"id:101,phase:1,t:lowercase,deny\" \nSecRule REQUEST_BODY \"@rx maliciouspayload\" \"id:102,phase:2,t:lowercase,deny\" \nSecRule RESPONSE_HEADERS::status \"@rx 406\" \"id:103,phase:3,t:lowercase,deny\" \nSecRule RESPONSE_BODY \"@contains responsebodycode\" \"id:104,phase:4,t:lowercase,deny\""
Expand Down
50 changes: 50 additions & 0 deletions internal/auditlog/serial_writer.go
Original file line number Diff line number Diff line change
@@ -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 }
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
2 changes: 2 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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())
})

Expand Down
10 changes: 7 additions & 3 deletions wasmplugin/rules/coraza-demo.conf
Original file line number Diff line number Diff line change
Expand Up @@ -221,17 +221,21 @@ SecDebugLogLevel 3
# trigger a server error (determined by a 5xx or 4xx, excluding 404,
# level response status codes).
#
SecAuditEngine On
SecAuditLogRelevantStatus "^(?:(5|4)(0|1)[0-9])$"
SecAuditEngine RelevantOnly
# SecAuditLogRelevantStatus includes status 0 as a workaround for https://github.com/corazawaf/coraza/pull/1097
SecAuditLogRelevantStatus "^(?:(5|4)(0|1)[0-9]|0)$"
M4tteoP marked this conversation as resolved.
Show resolved Hide resolved

# Log everything we know about a transaction.
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 -----------------------------------------------------------

Expand Down
10 changes: 7 additions & 3 deletions wasmplugin/rules/coraza.conf-recommended.conf
Original file line number Diff line number Diff line change
Expand Up @@ -220,17 +220,21 @@ SecResponseBodyLimitAction ProcessPartial
# trigger a server error (determined by a 5xx or 4xx, excluding 404,
# level response status codes).
#
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:(5|4)(0|1)[0-9])$"
SecAuditEngine Off
# SecAuditLogRelevantStatus includes status 0 as a workaround for https://github.com/corazawaf/coraza/pull/1097
SecAuditLogRelevantStatus "^(?:(5|4)(0|1)[0-9]|0)$"

# Log everything we know about a transaction.
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 -----------------------------------------------------------

Expand Down
Loading