diff --git a/internal/transformations/normalise_path.go b/internal/transformations/normalise_path.go index c83e5e9ad..802684cef 100644 --- a/internal/transformations/normalise_path.go +++ b/internal/transformations/normalise_path.go @@ -1,6 +1,8 @@ // Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors // SPDX-License-Identifier: Apache-2.0 +//go:build !windows + package transformations import ( @@ -16,7 +18,10 @@ func normalisePath(data string) (string, bool, error) { if clean == "." { return "", true, nil } - if data[len(data)-1] == '/' { + // filepath.Clean removes the trailing slash of a directory + // it is expected that the output of normalisePath keeps the trailing slash + // this if clause checks for trailing / and \ in the input as both are valid options + if data[len(data)-1] == '/' || data[len(data)-1] == '\\' { return clean + "/", true, nil } return clean, data != clean, nil diff --git a/internal/transformations/normalise_path_windows.go b/internal/transformations/normalise_path_windows.go new file mode 100644 index 000000000..6301cce92 --- /dev/null +++ b/internal/transformations/normalise_path_windows.go @@ -0,0 +1,30 @@ +// Copyright 2022 Juan Pablo Tosso and the OWASP Coraza contributors +// SPDX-License-Identifier: Apache-2.0 + +package transformations + +import ( + "path/filepath" + "strings" +) + +func normalisePath(data string) (string, bool, error) { + leng := len(data) + if leng < 1 { + return data, false, nil + } + clean := filepath.Clean(data) + // filepath.Clean uses filepath.Separator for the cleaned path + // on windows we need to replace the Separator with the expected forward slash + clean = strings.ReplaceAll(clean, string(filepath.Separator), "/") + if clean == "." { + return "", true, nil + } + // filepath.Clean removes the trailing slash of a directory + // it is expected that the output of normalisePath keeps the trailing slash + // this if clause checks for trailing / and \ in the input as both are valid options + if data[len(data)-1] == '/' || data[len(data)-1] == '\\' { + return clean + "/", true, nil + } + return clean, data != clean, nil +}