{"record":{"id":"bddf663992bb0a2b","repo":"larksuite/cli","slug":"s-must-not-contain-path-traversal","errorCode":null,"errorMessage":"%s must not contain '..' path traversal","messagePattern":"(.+?) must not contain '\\.\\.' path traversal","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/validate/resource.go","lineNumber":33,"sourceCode":"// unsafeResourceChars matches URL-special characters, control characters,\n// and percent signs (to prevent %2e%2e encoding bypass).\nvar unsafeResourceChars = regexp.MustCompile(`[?#%\\x00-\\x1f\\x7f]`)\n\n// ResourceName validates an API resource identifier (messageId, fileToken, etc.)\n// before it is interpolated into a URL path via fmt.Sprintf. It rejects path\n// traversal (..), URL metacharacters (?#%), percent-encoded bypasses (%2e%2e),\n// control characters, and dangerous Unicode.\n//\n// Without this check, an input like \"../admin\" or \"?evil=true\" in a message ID\n// would alter the API endpoint the request is sent to. Works alongside\n// EncodePathSegment for defense-in-depth.\nfunc ResourceName(name, flagName string) error {\n\tif name == \"\" {\n\t\treturn fmt.Errorf(\"%s must not be empty\", flagName)\n\t}\n\tfor _, seg := range strings.Split(name, \"/\") {\n\t\tif seg == \"..\" {\n\t\t\treturn fmt.Errorf(\"%s must not contain '..' path traversal\", flagName)\n\t\t}\n\t}\n\tif unsafeResourceChars.MatchString(name) {\n\t\treturn fmt.Errorf(\"%s contains invalid characters\", flagName)\n\t}\n\tfor _, r := range name {\n\t\tif charcheck.IsDangerousUnicode(r) {\n\t\t\treturn fmt.Errorf(\"%s contains dangerous Unicode characters\", flagName)\n\t\t}\n\t}\n\treturn nil\n}\n\n// EncodePathSegment percent-encodes user input for safe use as a single URL path\n// segment (e.g. / → %2F, ? → %3F, # → %23), ensuring the value cannot alter the\n// URL routing structure when interpolated into an API path.\n//\n// This provides defense-in-depth alongside ResourceName: ResourceName rejects known","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/validate/resource.go#L15-L51","documentation":"ResourceName splits the resource identifier on '/' and rejects any segment equal to '..', because path traversal could change which API endpoint the request targets (e.g. '../admin'). It is a defense-in-depth check alongside EncodePathSegment. The flag name is included so users know which input to fix.","triggerScenarios":"validate.ResourceName receives a name containing a '/'-separated '..' segment — e.g. --message-id '../../admin' or an app ID built from untrusted path-like input.","commonSituations":"Passing filesystem-style relative paths where an API resource ID is expected, constructing IDs by concatenating user-controlled parts, or malicious input attempting endpoint manipulation.","solutions":["Use the actual opaque resource ID (e.g. om_xxx, app id) — not a path.","Sanitize or reject path-like input before passing it; never build IDs from filesystem paths.","If the ID was copied from a URL, extract only the final identifier segment.","Use EncodePathSegment to percent-encode legitimate input containing slashes if the API expects encoded segments."],"exampleFix":"// before\nid=\"$tenant/$msgID\"\nlark-cli im message get --message-id \"$id\"\n// after\nlark-cli im message get --message-id \"$msgID\"  # pass the bare om_xxx ID only","handlingStrategy":"validation","validationCode":"for _, seg := range strings.Split(id, \"/\") {\n    if seg == \"..\" {\n        return fmt.Errorf(\"id must not contain path traversal\")\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := validate.ResourceName(id, \"--message-id\"); err != nil {\n    return fmt.Errorf(\"rejecting unsuitable id: %w\", err)\n}","preventionTips":["Never construct API resource IDs from filesystem paths or user-controlled path fragments.","Pass opaque IDs (om_xxx, app ids) exactly as returned by the API.","Extract only the identifier segment when copying from URLs.","Sanitize or reject path-like input at your application boundary."],"tags":["input-validation","security","path-traversal"],"backgroundTag":"path-traversal","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}