{"record":{"id":"09ee9c28cef6dcdf","repo":"dapr/dapr","slug":"name-is-a-path-traversal-sequence-q","errorCode":null,"errorMessage":"name is a path traversal sequence: %q","messagePattern":"name is a path traversal sequence: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/messaging/method/normalize.go","lineNumber":37,"sourceCode":"\t\"strings\"\n)\n\n// ValidateName checks that a name (e.g. reminder or timer name) does not\n// contain characters that could cause path traversal or injection when the\n// name is embedded in a URL path. Unlike NormalizeMethod, this rejects any\n// name containing '/' or '\\' since names are identifiers, not paths.\nfunc ValidateName(name string) error {\n\tif strings.ContainsAny(name, \"#?\\x00/\\\\\") {\n\t\treturn fmt.Errorf(\"name contains forbidden character: %q\", name)\n\t}\n\tfor i := range name {\n\t\tb := name[i]\n\t\tif b < 0x20 || b == 0x7f {\n\t\t\treturn fmt.Errorf(\"name contains control character at position %d: %q\", i, name)\n\t\t}\n\t}\n\tif name == \".\" || name == \"..\" {\n\t\treturn fmt.Errorf(\"name is a path traversal sequence: %q\", name)\n\t}\n\treturn nil\n}\n\n// NormalizeMethod validates and cleans a service invocation method name.\n// It rejects methods containing '#', '?', null bytes, or control characters\n// (bytes 0x01-0x1f and 0x7f), then resolves path traversal via path.Clean.\n// The caller is responsible for percent-decoding (for HTTP) before calling.\nfunc NormalizeMethod(method string) (string, error) {\n\tif strings.ContainsAny(method, \"#?\\x00\") {\n\t\treturn \"\", fmt.Errorf(\"method contains forbidden character: %q\", method)\n\t}\n\n\t// Reject control characters (0x01-0x1f and 0x7f DEL).\n\tfor i := range method {\n\t\tb := method[i]\n\t\tif b < 0x20 || b == 0x7f {\n\t\t\treturn \"\", fmt.Errorf(\"method contains control character at position %d: %q\", i, method)","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/dapr/dapr/blob/74ad41702745709bb15fe2114ff693b8c59bc3cc/pkg/messaging/method/normalize.go#L19-L55","documentation":"ValidateName rejects the exact names '.' and '..'. Because the name is embedded in a URL path, a relative path segment could resolve to an unexpected route on the actor host (path traversal), so the two dot forms are refused outright even though they contain no forbidden character. The error quotes the offending name for the log.","triggerScenarios":"Creating a reminder or timer named exactly '.' or '..': usually a defaulted, empty-ish, or path-normalized value (basename of an empty path, a config default, a TrimSpace leftover) passed as the name.","commonSituations":"Config templates whose name field is optional and normalizes to '.'; code that derives names from file paths and passes the cleaned relative segment; test fixtures using dot names.","solutions":["Require a meaningful name: minimum length and an allowlist charset (letters, digits, '_', '-', '.') that also rejects all-dot names","Default empty names to a generated ID instead of letting a dot fall through","Add a unit test asserting your name generator never emits '.', '..', or empty strings"],"exampleFix":"// before: derived name can collapse to '..'\nname := path.Clean(userPath) // '..'\nclient.CreateReminder(ctx, actorType, actorID, name, r)\n// -> name is a path traversal sequence: \"..\"\n\n// after: validate names through one guarded helper\nfunc safeName(s string) (string, error) {\n\tif !regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$`).MatchString(s) || s == \".\" || s == \"..\" {\n\t\treturn \"\", fmt.Errorf(\"invalid reminder name %q\", s)\n\t}\n\treturn s, nil\n}","handlingStrategy":"validation","validationCode":"var safeNameRe = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$`)\n\nfunc safeReminderName(s string) (string, error) {\n\tif !safeNameRe.MatchString(s) || s == \".\" || s == \"..\" {\n\t\treturn \"\", fmt.Errorf(\"invalid name %q\", s)\n\t}\n\treturn s, nil\n}","typeGuard":"func isPathTraversalName(name string) bool {\n\treturn name == \".\" || name == \"..\"\n}","tryCatchPattern":"if err := client.CreateReminder(ctx, actorType, actorID, name, r); err != nil {\n\tif strings.Contains(err.Error(), \"path traversal sequence\") {\n\t\treturn badRequest(\"name must be a meaningful identifier\")\n\t}\n\treturn err\n}","preventionTips":["Never pass path-derived or config-defaulted values as names without an allowlist check","Reject empty and all-dot names explicitly in your own validation layer","Unit-test name generators to prove they cannot emit '.', '..', or empty strings"],"tags":["validation","security","path-traversal","actors"],"backgroundTag":null,"analyzedSha":"74ad41702745709bb15fe2114ff693b8c59bc3cc","analyzedAt":"2026-08-16T04:22:26.543Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}