{"record":{"id":"7d50597ecd00288e","repo":"larksuite/cli","slug":"s-contains-dangerous-unicode-characters","errorCode":null,"errorMessage":"%s contains dangerous Unicode characters","messagePattern":"(.+?) contains dangerous Unicode characters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/charcheck/charcheck.go","lineNumber":21,"sourceCode":"\n// Package charcheck provides character-level security checks shared across\n// path validation (localfileio) and input validation (validate) packages.\n// Keeping these checks in one place ensures consistent detection of dangerous\n// Unicode and control characters throughout the codebase.\npackage charcheck\n\nimport \"fmt\"\n\n// RejectControlChars rejects C0 control characters (except \\t and \\n) and\n// dangerous Unicode characters (Bidi overrides, zero-width, line/paragraph\n// separators) that enable visual spoofing attacks.\nfunc RejectControlChars(value, flagName string) error {\n\tfor _, r := range value {\n\t\tif r != '\\t' && r != '\\n' && (r < 0x20 || r == 0x7f) {\n\t\t\treturn fmt.Errorf(\"%s contains invalid control characters\", flagName)\n\t\t}\n\t\tif 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// IsDangerousUnicode identifies Unicode code points used for visual spoofing\n// attacks. These characters are invisible or alter text direction, allowing\n// attackers to make \"report.exe\" display as \"report.txt\" (Bidi override) or\n// insert hidden content (zero-width characters).\nfunc IsDangerousUnicode(r rune) bool {\n\tswitch {\n\tcase r >= 0x200B && r <= 0x200D: // zero-width space/non-joiner/joiner\n\t\treturn true\n\tcase r == 0xFEFF: // BOM / ZWNBSP\n\t\treturn true\n\tcase r >= 0x202A && r <= 0x202E: // Bidi: LRE/RLE/PDF/LRO/RLO\n\t\treturn true\n\tcase r >= 0x2028 && r <= 0x2029: // line/paragraph separator","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/charcheck/charcheck.go#L3-L39","documentation":"RejectControlChars also rejects Unicode code points known to enable visual spoofing: bidirectional overrides, zero-width characters, and line/paragraph separators. A string containing these looks different from what it actually is (e.g. reversed filename extensions), so the library treats them as invalid input.","triggerScenarios":"A flag value containing U+202E (RLO), U+200B (zero-width space), U+2028/U+2029, or similar detected by IsDangerousUnicode, on any RejectControlChars-guarded input.","commonSituations":"Usernames or filenames crafted (or copy-pasted) with invisible/bidi characters; multilingual text with zero-width joiners from social platforms; homograph-spoofed file names.","solutions":["Remove the dangerous Unicode characters from the value","Retype the value manually in plain ASCII or clean Unicode","Normalize with a Unicode normalizer and strip bidi/zero-width code points before passing"],"exampleFix":"// before\nname := \"report\\u202Etxt.exe\" // RLO reversal\n// after\nname := \"report.txt\"","handlingStrategy":"validation","validationCode":"func hasDangerousUnicode(s string) bool {\n    for _, r := range s {\n        if IsDangerousUnicode(r) { return true }\n    }\n    return false\n}\nif hasDangerousUnicode(fileName) { fileName = sanitizeUnicode(fileName) }","typeGuard":"func isUnicodeSafe(s string) bool {\n    for _, r := range s {\n        if IsDangerousUnicode(r) { return false }\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Normalize user filenames with golang.org/x/text/unicode/norm","Strip bidi/zero-width code points at ingestion boundaries","Be extra careful with filenames from untrusted sources (spoofing vector)"],"tags":["security","validation","unicode","spoofing"],"backgroundTag":"dangerous-unicode-characters","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"}