MCPcopy
hub / github.com/codeaashu/claude-code / checkStartProcess

Function checkStartProcess

src/tools/PowerShellTool/powershellSecurity.ts:550–633  ·  view source on GitHub ↗

* Checks for dangerous Start-Process patterns. * * Two vectors: * 1. `-Verb RunAs` — privilege escalation (UAC prompt). * 2. Launching a PowerShell executable — nested invocation. * `Start-Process pwsh -ArgumentList "-e "` evades * checkEncodedCommand/checkPwshCommandOrFile because cmd.na

(
  parsed: ParsedPowerShellCommand,
)

Source from the content-addressed store, hash-verified

548 * executable: the nested invocation is unvalidatable by construction.
549 */
550function checkStartProcess(
551 parsed: ParsedPowerShellCommand,
552): PowerShellSecurityResult {
553 for (const cmd of getAllCommands(parsed)) {
554 const lower = cmd.name.toLowerCase()
555 if (lower !== 'start-process' && lower !== 'saps' && lower !== 'start') {
556 continue
557 }
558 // Vector 1: -Verb RunAs (space or colon syntax).
559 // Space syntax: psExeHasParamAbbreviation finds -Verb/-v, then scan args
560 // for a bare 'runas' token.
561 if (
562 psExeHasParamAbbreviation(cmd, '-Verb', '-v') &&
563 cmd.args.some(a => a.toLowerCase() === 'runas')
564 ) {
565 return {
566 behavior: 'ask',
567 message: 'Command requests elevated privileges',
568 }
569 }
570 // Colon syntax — two layers:
571 // (a) Structural: PR #23554 added children[] for colon-bound param args.
572 // children[i] = [{type, text}] for the bound value. Check if any
573 // -v*-prefixed param has a child whose text normalizes (strip
574 // quotes/backtick/whitespace) to 'runas'. Robust against arbitrary
575 // quoting the regex can't anticipate.
576 // (b) Regex fallback: for parsed output without children[] or as
577 // defense-in-depth. -Verb:'RunAs', -Verb:"RunAs", -Verb:`runas all
578 // bypassed the old /...:runas$/ pattern because the quote/tick broke
579 // the match.
580 if (cmd.children) {
581 for (let i = 0; i < cmd.args.length; i++) {
582 // Strip backticks before matching param name (bug #14): -V`erb:RunAs
583 const argClean = cmd.args[i]!.replace(/`/g, '')
584 if (!/^[-\u2013\u2014\u2015/]v[a-z]*:/i.test(argClean)) continue
585 const kids = cmd.children[i]
586 if (!kids) continue
587 for (const child of kids) {
588 if (child.text.replace(/['"`\s]/g, '').toLowerCase() === 'runas') {
589 return {
590 behavior: 'ask',
591 message: 'Command requests elevated privileges',
592 }
593 }
594 }
595 }
596 }
597 if (
598 cmd.args.some(a => {
599 // Strip backticks before matching (bug #14 / review nit #2)
600 const clean = a.replace(/`/g, '')
601 return /^[-\u2013\u2014\u2015/]v[a-z]*:['"` ]*runas['"` ]*$/i.test(
602 clean,
603 )
604 })
605 ) {
606 return {
607 behavior: 'ask',

Callers

nothing calls this directly

Calls 3

isPowerShellExecutableFunction · 0.85
getAllCommandsFunction · 0.50

Tested by

no test coverage detected