From 312e779ca3be69ff29aadda635b863d7c15fa059 Mon Sep 17 00:00:00 2001 From: Alex Snaps Date: Wed, 13 Nov 2024 09:57:39 -0500 Subject: [PATCH] Case insensitive header matching and safe lookup Signed-off-by: Alex Snaps --- pkg/wasm/utils.go | 7 +++++-- pkg/wasm/utils_test.go | 8 ++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pkg/wasm/utils.go b/pkg/wasm/utils.go index 5fffe8eb3..30023b71c 100644 --- a/pkg/wasm/utils.go +++ b/pkg/wasm/utils.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "strings" "github.com/kuadrant/policy-machinery/machinery" "github.com/samber/lo" @@ -179,9 +180,11 @@ func predicateFromMethod(method gatewayapiv1.HTTPMethod) string { func predicateFromHeader(headerMatch gatewayapiv1.HTTPHeaderMatch) string { // As for gateway api v1, the only operation type with core support is Exact match. // https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPHeaderMatch - return fmt.Sprintf("request.headers['%s'] == '%s'", headerMatch.Name, headerMatch.Value) + return fmt.Sprintf("request.headers.exists(h, h.lowerAscii() == '%s' && request.headers[h] == '%s')", + strings.ToLower(string(headerMatch.Name)), headerMatch.Value) } func predicateFromQueryParam(queryParam gatewayapiv1.HTTPQueryParamMatch) string { - return fmt.Sprintf("queryMap(request.query)['%s'] == '%s'", queryParam.Name, queryParam.Value) + return fmt.Sprintf("'%s' in queryMap(request.query) ? queryMap(request.query)['%s'] == '%s' : false", + queryParam.Name, queryParam.Name, queryParam.Value) } diff --git a/pkg/wasm/utils_test.go b/pkg/wasm/utils_test.go index a6074996c..ba76107e0 100644 --- a/pkg/wasm/utils_test.go +++ b/pkg/wasm/utils_test.go @@ -262,7 +262,7 @@ func TestPredicatesFromHTTPRouteMatch(t *testing.T) { headerMatch := gatewayapiv1.HeaderMatchExact header := gatewayapiv1.HTTPHeaderMatch{ Type: &headerMatch, - Name: "x-auth", + Name: "X-Auth", Value: "kuadrant", } @@ -282,8 +282,8 @@ func TestPredicatesFromHTTPRouteMatch(t *testing.T) { assert.Equal(t, predicates[0], "request.method == 'TRACE'") assert.Equal(t, predicates[1], "request.url_path.startsWith('/admin')") - assert.Equal(t, predicates[2], "request.headers['x-auth'] == 'kuadrant'") - assert.Equal(t, predicates[3], "queryMap(request.query)['foo'] == 'bar'") - assert.Equal(t, predicates[4], "queryMap(request.query)['kua'] == 'drant'") + assert.Equal(t, predicates[2], "request.headers.exists(h, h.lowerAscii() == 'x-auth' && request.headers[h] == 'kuadrant')") + assert.Equal(t, predicates[3], "'foo' in queryMap(request.query) ? queryMap(request.query)['foo'] == 'bar' : false") + assert.Equal(t, predicates[4], "'kua' in queryMap(request.query) ? queryMap(request.query)['kua'] == 'drant' : false") assert.Equal(t, len(predicates), 5) }