{"record":{"id":"3864ea9f124ed5eb","repo":"larksuite/cli","slug":"s-contains-invalid-control-characters","errorCode":null,"errorMessage":"%s contains invalid control characters","messagePattern":"(.+?) contains invalid control characters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/charcheck/charcheck.go","lineNumber":18,"sourceCode":"// Copyright (c) 2026 Lark Technologies Pte. Ltd.\n// SPDX-License-Identifier: MIT\n\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","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/charcheck/charcheck.go#L1-L36","documentation":"RejectControlChars flags C0 control characters (excluding tab and newline) such as 0x00-0x1F and 0x7F in a user-supplied string. These characters are invisible or terminal-altering and enable spoofing/argument-injection, so the library rejects them at input validation time.","triggerScenarios":"Passing a flag value containing e.g. \\x00, \\x1b (escape sequences), or \\r to any validated input path such as LocalInputPath, SafeEnvDirPath, or resolveTargetPath callers.","commonSituations":"Copying text with hidden control bytes from PDFs or terminals; binary content read as text; shell heredocs adding trailing control chars; paste from Windows CRLF sources introducing stray bytes.","solutions":["Remove the control characters (keep only printable text plus tab/newline)","Re-encode or re-copy the value from a clean source","Sanitize the string programmatically, stripping runes < 0x20 (except \\t, \\n) and 0x7F before passing it"],"exampleFix":"// before\nflag := \"report\\x1b[31m.txt\"\n// after\nclean := strings.Map(func(r rune) rune {\n    if (r != '\\t' && r != '\\n' && r < 0x20) || r == 0x7f {\n        return -1\n    }\n    return r\n}, flag)","handlingStrategy":"validation","validationCode":"func hasControlChars(s string) bool {\n    for _, r := range s {\n        if r != '\\t' && r != '\\n' && (r < 0x20 || r == 0x7f) {\n            return true\n        }\n    }\n    return false\n}\n// call before invoking the command\nif hasControlChars(userValue) { return errors.New(\"value contains control characters\") }","typeGuard":"func isCleanInput(s string) bool {\n    for _, r := range s {\n        if r != '\\t' && r != '\\n' && (r < 0x20 || r == 0x7f) || IsDangerousUnicode(r) {\n            return false\n        }\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Sanitize copy-pasted or externally sourced strings before use","Strip < 0x20 (except \\t,\\n) and 0x7F in a shared input-normalization helper","Avoid binary-as-text inputs; decode explicitly first"],"tags":["security","validation","input-sanitization"],"backgroundTag":"control-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"}