{"record":{"id":"dd7c44e61dfac011","repo":"larksuite/cli","slug":"s-contains-dangerous-unicode-characters-dd7c44","errorCode":null,"errorMessage":"%s contains dangerous Unicode characters","messagePattern":"(.+?) contains dangerous Unicode characters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/validate/resource.go","lineNumber":41,"sourceCode":"//\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\n// dangerous patterns at the input layer, while EncodePathSegment acts as a fallback\n// at the concatenation layer — if ResourceName rules are relaxed in the future, or\n// if an API path bypasses ResourceName validation (e.g. cmd/service/ generic calls),\n// encoding still prevents special characters from being interpreted as path separators\n// or query parameters.\n//\n// Convention: all user-provided variables in fmt.Sprintf API paths within shortcuts/\n// MUST be wrapped with this function.","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/validate/resource.go#L23-L59","documentation":"ResourceName iterates the identifier's runes and rejects any character for which charcheck.IsDangerousUnicode returns true — e.g. bidi controls, zero-width, or homoglyph-confusable characters. This stops visually deceptive or control-bearing IDs from being sent to the API. The flag name identifies which input to correct.","triggerScenarios":"validate.ResourceName receives a name containing dangerous Unicode (bidi/zero-width/control characters), detected per-rune via charcheck.IsDangerousUnicode.","commonSituations":"IDs copy-pasted from rich-text documents or chat messages carrying invisible formatting characters, CSV/spreadsheet exports with BOM or zero-width spaces, or crafted spoofed identifiers.","solutions":["Re-copy the ID from a plain-text source (terminal, API JSON) rather than rich text.","Strip invisible characters with a Unicode-stripping filter before use.","Fetch the canonical ID again via the API (list/search) instead of pasting.","Inspect the input with `hexdump -C` to find hidden characters."],"exampleFix":"// before\nlark-cli im message get --message-id \"$ID\"   # ID copied from a doc, contains U+200B\n// after\nID=$(printf '%s' \"$ID\" | perl -CS -pe 's/[\\x{200B}-\\x{200F}\\x{202A}-\\x{202E}\\x{FEFF}]//g')\nlark-cli im message get --message-id \"$ID\"","handlingStrategy":"validation","validationCode":"for _, r := range id {\n    if charcheck.IsDangerousUnicode(r) {\n        return fmt.Errorf(\"id contains dangerous Unicode (bidi/zero-width) characters\")\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := validate.ResourceName(id, \"--message-id\"); err != nil {\n    return fmt.Errorf(\"re-copy the id from a plain-text source: %w\", err)\n}","preventionTips":["Copy identifiers from plain-text sources, not rich-text documents or chat bubbles.","Strip zero-width/bidi/control characters programmatically before use.","Re-fetch canonical IDs via API list/search endpoints instead of pasting.","Inspect suspicious inputs with hexdump to detect invisible characters."],"tags":["input-validation","security","unicode"],"backgroundTag":"invalid-characters-in-input","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"}