MCPcopy Index your code
hub / github.com/codeaashu/claude-code / checkComObject

Function checkComObject

src/tools/PowerShellTool/powershellSecurity.ts:343–429  ·  view source on GitHub ↗

* Checks for New-Object -ComObject. COM objects like WScript.Shell, * Shell.Application, MMC20.Application, Schedule.Service, Msxml2.XMLHTTP * have their own execution/download capabilities — no IEX required. * * We can't enumerate all dangerous ProgIDs, so flag any -ComObject. Object * creatio

(
  parsed: ParsedPowerShellCommand,
)

Source from the content-addressed store, hash-verified

341 * (.Run(), .Exec()) is separately caught by checkMemberInvocations.
342 */
343function checkComObject(
344 parsed: ParsedPowerShellCommand,
345): PowerShellSecurityResult {
346 for (const cmd of getAllCommands(parsed)) {
347 if (cmd.name.toLowerCase() !== 'new-object') {
348 continue
349 }
350 // -ComObject min abbrev is -com (New-Object params: -TypeName, -ComObject,
351 // -ArgumentList, -Property, -Strict; -co is ambiguous in PS5.1 due to
352 // common params like -Confirm, so use -com).
353 if (psExeHasParamAbbreviation(cmd, '-comobject', '-com')) {
354 return {
355 behavior: 'ask',
356 message:
357 'Command instantiates a COM object which may have execution capabilities',
358 }
359 }
360 // SECURITY: checkTypeLiterals only sees [bracket] syntax from
361 // parsed.typeLiterals. `New-Object System.Net.WebClient` passes the type
362 // as a STRING ARG (StringConstantExpressionAst), not a TypeExpressionAst,
363 // so CLM never fires. Extract -TypeName (named, colon-bound, or
364 // positional-0) and run through isClmAllowedType. Closes attackVectors D4.
365 let typeName: string | undefined
366 for (let i = 0; i < cmd.args.length; i++) {
367 const a = cmd.args[i]!
368 const lower = a.toLowerCase()
369 // -TypeName abbrev: -t is unambiguous (no other New-Object -t* params).
370 // Handle colon-bound form first: -TypeName:Foo.Bar
371 if (lower.startsWith('-t') && lower.includes(':')) {
372 const colonIdx = a.indexOf(':')
373 const paramPart = lower.slice(0, colonIdx)
374 if ('-typename'.startsWith(paramPart)) {
375 typeName = a.slice(colonIdx + 1)
376 break
377 }
378 }
379 // Space-separated form: -TypeName Foo.Bar
380 if (
381 lower.startsWith('-t') &&
382 '-typename'.startsWith(lower) &&
383 cmd.args[i + 1] !== undefined
384 ) {
385 typeName = cmd.args[i + 1]
386 break
387 }
388 }
389 // Positional-0 binds to -TypeName (NetParameterSet default). Named params
390 // (-Strict, -ArgumentList, -Property, -ComObject) may appear before the
391 // positional TypeName, so scan past them to find the first non-consumed arg.
392 if (typeName === undefined) {
393 // New-Object named params that consume a following value argument
394 const VALUE_PARAMS = new Set(['-argumentlist', '-comobject', '-property'])
395 // Switch params (no value argument)
396 const SWITCH_PARAMS = new Set(['-strict'])
397 for (let i = 0; i < cmd.args.length; i++) {
398 const a = cmd.args[i]!
399 if (a.startsWith('-')) {
400 const lower = a.toLowerCase()

Callers

nothing calls this directly

Calls 4

isClmAllowedTypeFunction · 0.85
getAllCommandsFunction · 0.50
hasMethod · 0.45

Tested by

no test coverage detected