teleport icon indicating copy to clipboard operation
teleport copied to clipboard

`regexp.replace` Fails with Curly Brackets in Teleport Role Interpolation

Open programmerq opened this issue 9 months ago • 2 comments

Expected behavior:

The regexp.replace function should correctly handle regular expressions that include curly brackets {} for specifying matches, such as regexp.replace(external.some_external_list, "^str_to_match:(.{0,28}).*$", "usr-$1"). This should truncate the matching string to 28 characters.

Current behavior:

The regexp.replace function fails to process regular expressions with curly brackets {} within role interpolation logic. The template parsing layer treats it as an invalid match.

Bug details:

  • Teleport version: observed on 15.3.5
  • Recreation steps:
    1. Define a role with regexp.replace using a regex that includes curly brackets, e.g.:
      kind: role
      metadata:
        name: example_role
      spec:
        allow:
          db_users:
          - '{{regexp.replace(external.some_external_list, "^str_to_match:(.{0,28}).*$","user-$1")}}'
      
    2. Define a user with appropriate traits:
      kind: user
      spec:
        roles:
        - example_role
        traits:
          some_external_list:
          - str_to_match:database-user
          - str_to_match:verylongdatabaseuserthatneedstobetruncated
      
    3. Inspect the user's generated db_users on the Teleport user's certificate. Any regex that includes a curly bracket produces no output. No user-facing errors surface.

Additional info

While testing, I added this Test case added to TestVariable in parse_test.go:

{
  title: "regexp replace with curly brackets",
  in:    `{{regexp.replace(internal.foo, "^f.{0,3}.*$", "$1")}}`,
  out:   "oov",
}

Running the test produces:

GOROOT=/usr/local/opt/go/libexec #gosetup
GOPATH=/Users/jeff/go #gosetup
/usr/local/opt/go/libexec/bin/go test -c -o /Users/jeff/Library/Caches/JetBrains/GoLand2024.1/tmp/GoLand/___TestVariable_regexp_replace_with_curly_brackets_in_github_com_gravitational_teleport_lib_utils_parse.test github.com/gravitational/teleport/lib/utils/parse #gosetup
/usr/local/opt/go/libexec/bin/go tool test2json -t /Users/jeff/Library/Caches/JetBrains/GoLand2024.1/tmp/GoLand/___TestVariable_regexp_replace_with_curly_brackets_in_github_com_gravitational_teleport_lib_utils_parse.test -test.v -test.paniconexit0 -test.run ^\QTestVariable\E$/^\Qregexp_replace_with_curly_brackets\E$
=== RUN   TestVariable
=== PAUSE TestVariable
=== CONT  TestVariable
=== RUN   TestVariable/regexp_replace_with_curly_brackets
    parse_test.go:202: 
        	Error Trace:	/Users/jeff/workspace/teleport/lib/utils/parse/parse_test.go:202
        	Error:      	Received unexpected error:
        	            	"{{regexp.replace(internal.foo, \"^f.{0,3}.*$\", \"$1\")}}" is using template brackets '{{' or '}}', however expression does not parse, make sure the format is {{expression}}
        	Test:       	TestVariable/regexp_replace_with_curly_brackets
        	Messages:   	
        	            	ERROR REPORT:
        	            	Original Error: *trace.BadParameterError "{{regexp.replace(internal.foo, \"^f.{0,3}.*$\", \"$1\")}}" is using template brackets '{{' or '}}', however expression does not parse, make sure the format is {{expression}}
        	            	Stack Trace:
        	            		/Users/jeff/workspace/teleport/lib/utils/parse/parse.go:82 github.com/gravitational/teleport/lib/utils/parse.NewTraitsTemplateExpression
        	            		/Users/jeff/workspace/teleport/lib/utils/parse/parse_test.go:197 github.com/gravitational/teleport/lib/utils/parse.TestVariable.func1
        	            		/usr/local/opt/go/libexec/src/testing/testing.go:1689 testing.tRunner
        	            		/usr/local/opt/go/libexec/src/runtime/asm_amd64.s:1695 runtime.goexit
        	            	User Message: "{{regexp.replace(internal.foo, \"^f.{0,3}.*$\", \"$1\")}}" is using template brackets '{{' or '}}', however expression does not parse, make sure the format is {{expression}}
--- FAIL: TestVariable (0.00s)
    --- FAIL: TestVariable/regexp_replace_with_curly_brackets (0.00s)


FAIL

Process finished with the exit code 1

It looks like this is the regex that fails the match:

https://github.com/gravitational/teleport/blob/v15.3.1/lib/utils/parse/parse.go#L54-L61

https://github.com/gravitational/teleport/blob/1d048d0736fcb65b65bc513e328d7c98cbfe3d23/lib/utils/parse/parse.go#L54-L61

programmerq avatar May 17 '24 17:05 programmerq