MCPcopy Create free account
hub / github.com/codeaashu/claude-code / validateCarriageReturn

Function validateCarriageReturn

src/tools/BashTool/bashSecurity.ts:971–1015  ·  view source on GitHub ↗

* SECURITY: Carriage return (\r, 0x0D) IS a misparsing concern, unlike LF. * * Parser differential: * - shell-quote's BAREWORD regex uses `[^\s...]` — JS `\s` INCLUDES \r, so * shell-quote treats CR as a token boundary. `TZ=UTC\recho` tokenizes as * TWO tokens: ['TZ=UTC', 'echo']. spl

(context: ValidationContext)

Source from the content-addressed store, hash-verified

969 * and shell-quote preserves the token (no split).
970 */
971function validateCarriageReturn(context: ValidationContext): PermissionResult {
972 const { originalCommand } = context
973
974 if (!originalCommand.includes('\r')) {
975 return { behavior: 'passthrough', message: 'No carriage return' }
976 }
977
978 // Check if CR appears outside double quotes. CR outside DQ (including inside
979 // SQ and unquoted) causes the shell-quote/bash tokenization differential.
980 let inSingleQuote = false
981 let inDoubleQuote = false
982 let escaped = false
983 for (let i = 0; i < originalCommand.length; i++) {
984 const c = originalCommand[i]
985 if (escaped) {
986 escaped = false
987 continue
988 }
989 if (c === '\\' && !inSingleQuote) {
990 escaped = true
991 continue
992 }
993 if (c === "'" && !inDoubleQuote) {
994 inSingleQuote = !inSingleQuote
995 continue
996 }
997 if (c === '"' && !inSingleQuote) {
998 inDoubleQuote = !inDoubleQuote
999 continue
1000 }
1001 if (c === '\r' && !inDoubleQuote) {
1002 logEvent('tengu_bash_security_check_triggered', {
1003 checkId: BASH_SECURITY_CHECK_IDS.NEWLINES,
1004 subId: 2,
1005 })
1006 return {
1007 behavior: 'ask',
1008 message:
1009 'Command contains carriage return (\\r) which shell-quote and bash tokenize differently',
1010 }
1011 }
1012 }
1013
1014 return { behavior: 'passthrough', message: 'CR only inside double quotes' }
1015}
1016
1017function validateIFSInjection(context: ValidationContext): PermissionResult {
1018 const { originalCommand } = context

Callers

nothing calls this directly

Calls 1

logEventFunction · 0.85

Tested by

no test coverage detected