MCPcopy Create free account
hub / github.com/claude-code-best/claude-code / parseForSecurityFromAst

Function parseForSecurityFromAst

src/utils/bash/ast.ts:401–461  ·  view source on GitHub ↗
(
  cmd: string,
  root: Node | typeof PARSE_ABORTED,
)

Source from the content-addressed store, hash-verified

399 * successful parse doesn't.
400 */
401export function parseForSecurityFromAst(
402 cmd: string,
403 root: Node | typeof PARSE_ABORTED,
404): ParseForSecurityResult {
405 // Pre-checks: characters that cause tree-sitter and bash to disagree on
406 // word boundaries. These run before tree-sitter because they're the known
407 // tree-sitter/bash differentials. Everything after this point trusts
408 // tree-sitter's tokenization.
409 if (CONTROL_CHAR_RE.test(cmd)) {
410 return { kind: 'too-complex', reason: 'Contains control characters' }
411 }
412 if (UNICODE_WHITESPACE_RE.test(cmd)) {
413 return { kind: 'too-complex', reason: 'Contains Unicode whitespace' }
414 }
415 if (BACKSLASH_WHITESPACE_RE.test(cmd)) {
416 return {
417 kind: 'too-complex',
418 reason: 'Contains backslash-escaped whitespace',
419 }
420 }
421 if (ZSH_TILDE_BRACKET_RE.test(cmd)) {
422 return {
423 kind: 'too-complex',
424 reason: 'Contains zsh ~[ dynamic directory syntax',
425 }
426 }
427 if (ZSH_EQUALS_EXPANSION_RE.test(cmd)) {
428 return {
429 kind: 'too-complex',
430 reason: 'Contains zsh =cmd equals expansion',
431 }
432 }
433 if (BRACE_WITH_QUOTE_RE.test(maskBracesInQuotedContexts(cmd))) {
434 return {
435 kind: 'too-complex',
436 reason: 'Contains brace with quote character (expansion obfuscation)',
437 }
438 }
439
440 const trimmed = cmd.trim()
441 if (trimmed === '') {
442 return { kind: 'simple', commands: [] }
443 }
444
445 if (root === PARSE_ABORTED) {
446 // SECURITY: module loaded but parse aborted (timeout / node budget /
447 // panic). Adversarially triggerable — `(( a[0][0]... ))` with ~2800
448 // subscripts hits PARSE_TIMEOUT_MICROS under the 10K length limit.
449 // Previously indistinguishable from module-not-loaded → routed to
450 // legacy (parse-unavailable), which lacks EVAL_LIKE_BUILTINS — `trap`,
451 // `enable`, `hash` leaked with Bash(*). Fail closed: too-complex → ask.
452 return {
453 kind: 'too-complex',
454 reason:
455 'Parser aborted (timeout or resource limit) — possible adversarial input',
456 nodeType: 'PARSE_ABORT',
457 }
458 }

Callers 2

bashToolHasPermissionFunction · 0.85
parseForSecurityFunction · 0.85

Calls 2

walkProgramFunction · 0.85

Tested by

no test coverage detected