add JA4H expr helper (#3401)

This commit is contained in:
blotus 2025-02-24 15:20:33 +01:00 committed by GitHub
parent a3187d6f2c
commit ce5b4b435b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 656 additions and 6 deletions

View file

@ -2,6 +2,7 @@ package exprhelpers
import (
"net"
"net/http"
"time"
"github.com/oschwald/geoip2-golang"
@ -493,6 +494,13 @@ var exprFuncs = []exprCustomFunc{
new(func(string) *net.IPNet),
},
},
{
name: "JA4H",
function: JA4H,
signature: []interface{}{
new(func(*http.Request) string),
},
},
}
//go 1.20 "CutPrefix": strings.CutPrefix,

13
pkg/exprhelpers/waf.go Normal file
View file

@ -0,0 +1,13 @@
package exprhelpers
import (
"net/http"
"github.com/crowdsecurity/crowdsec/pkg/appsec/ja4h"
)
// JA4H(req *http.Request) string
func JA4H(params ...any) (any, error) {
req := params[0].(*http.Request)
return ja4h.JA4H(req), nil
}

View file

@ -0,0 +1,78 @@
package exprhelpers
import (
"net/http"
"testing"
"github.com/stretchr/testify/require"
)
func TestJA4H(t *testing.T) {
tests := []struct {
name string
method string
url string
cookies map[string]string
headers map[string]string
expectedHash string
}{
{
name: "Basic GET - No cookies",
method: "GET",
url: "http://example.com",
cookies: map[string]string{},
headers: map[string]string{},
expectedHash: "ge11nn000000_e3b0c44298fc_000000000000_000000000000",
},
{
name: "Basic POST - No cookies",
method: "POST",
url: "http://example.com",
cookies: map[string]string{},
headers: map[string]string{},
expectedHash: "po11nn000000_e3b0c44298fc_000000000000_000000000000",
},
{
name: "GET - With cookies",
method: "GET",
url: "http://example.com/foobar",
cookies: map[string]string{
"foo": "bar",
"baz": "qux",
},
headers: map[string]string{
"User-Agent": "Mozilla/5.0",
},
expectedHash: "ge11cn010000_b8bcd45ac095_bd87575d11f6_d401f362552e",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
req, err := http.NewRequest(test.method, test.url, nil)
if err != nil {
t.Fatalf("Failed to create request: %s", err)
}
for key, value := range test.cookies {
req.AddCookie(&http.Cookie{
Name: key,
Value: value,
})
}
for key, value := range test.headers {
req.Header.Add(key, value)
}
hash, err := JA4H(req)
require.NoError(t, err)
if hash != test.expectedHash {
t.Fatalf("JA4H returned unexpected hash: %s", hash)
}
})
}
}