diff --git a/experimental/plugins/plugintypes/transformation.go b/experimental/plugins/plugintypes/transformation.go index e9b699b16..0d1b87e8a 100644 --- a/experimental/plugins/plugintypes/transformation.go +++ b/experimental/plugins/plugintypes/transformation.go @@ -8,4 +8,6 @@ package plugintypes // If a transformation fails to run it will return the same string // and an error, errors are only used for logging, it won't stop // the execution of the rule -type Transformation = func(input string) (string, bool, error) +// "updated" is used for transformation cache, if true, the cache +// will be updated +type Transformation = func(input string) (result string, updated bool, err error) diff --git a/internal/transformations/reverse.go b/internal/transformations/reverse.go new file mode 100644 index 000000000..e80cad640 --- /dev/null +++ b/internal/transformations/reverse.go @@ -0,0 +1,18 @@ +// Copyright 2023 Juan Pablo Tosso and the OWASP Coraza contributors +// SPDX-License-Identifier: Apache-2.0 + +package transformations + +func reverse(data string) (string, bool, error) { + if len(data) <= 1 { + return data, false, nil + } + rns := []rune(data) // convert to rune, not bytes + for i, j := 0, len(rns)-1; i < j; i, j = i+1, j-1 { + // swap the letters of the string, + // like first with last and so on. + rns[i], rns[j] = rns[j], rns[i] + } + res := string(rns) + return res, res != data, nil +} diff --git a/internal/transformations/testdata/reverse.json b/internal/transformations/testdata/reverse.json new file mode 100644 index 000000000..abb642f70 --- /dev/null +++ b/internal/transformations/testdata/reverse.json @@ -0,0 +1,38 @@ +[ + { + "output": "desrever si siht", + "name": "reverse", + "input": "this is reversed", + "type": "tfn", + "ret": 0 + }, + { + "output": "síht sì dèsrèvèr", + "name": "reverse", + "input": "rèvèrsèd ìs thís", + "type": "tfn", + "ret": 0 + }, + { + "output": "esaC\u0000tseT", + "name": "reverse", + "input": "Test\u0000Case", + "type": "tfn", + "ret": 0 + }, + { + "output": "", + "name": "reverse", + "input": "", + "type": "tfn", + "ret": 0 + }, + { + "output": "a", + "name": "reverse", + "input": "a", + "type": "tfn", + "ret": 0 + } + +] \ No newline at end of file diff --git a/internal/transformations/transformations.go b/internal/transformations/transformations.go index 75a9f58fa..2dd7365cc 100644 --- a/internal/transformations/transformations.go +++ b/internal/transformations/transformations.go @@ -50,6 +50,7 @@ func init() { Register("removeWhitespace", removeWhitespace) Register("replaceComments", replaceComments) Register("replaceNulls", replaceNulls) + Register("reverse", reverse) Register("sha1", sha1T) Register("uppercase", upperCase) Register("urlDecode", urlDecode)