psscriptanalyzer feels invoke-expression is bad.

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Warren Frame Warren Frame 7 months, 3 weeks ago.

  • Author
    Posts
  • #37527
    Profile photo of Justin King
    Justin King
    Participant

    I have a few build scripts that call non-powershell EXEs to do work simply because of the lack of cmdlets available and my unwillingness to reverse engineer exactly what the supplied command line programs do. I tend to call them using invoke-expression after building the exact syntax in a variable. So for example, a very little snippet:

    $cmd = 'certutil.exe -setreg CA\CRLPublicationURLs "1:'+$env:SystemRoot+'\system32\CertSrv\CertEnroll\%3%8%9.crl\n2:http://'+$FQDN+'/pki/%3%8%9.crl"'
    Invoke-Expression $cmd | Write-Verbose
    

    I've noticed PSScriptAnalyzer really doesn't like me using Invoke-Expression like ... at all. So while I correct most of the recommendations this is one I've ignored over time.

    What is the best -practice reasoning for avoiding invoke-expression? Is it because of a code-injection risk? I think the context would help me to determine under which cases I should indeed go down the path of making my own tools vs. saying "meh, for this scenario it's fine".

  • #37528
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Yes, Invoke-Expression opens you up to code injection attacks. Even when calling an external command like certutil.exe, you don't need to use Invoke-Expression; this is safe, and accomplishes the same thing:

    certutil.exe -setreg CA\CRLPublicationURLs "1:$env:SystemRoot\system32\CertSrv\CertEnroll\%3%8%9.crl\n2:http://$FQDN/pki/%3%8%9.crl" |
    Write-Verbose
    
  • #37529
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    That said, if you completely control the variables that are being used to construct your command (no outside input at all), then there is not really any risk involved. However, here's an example of what might happen if $FQDN were loaded up from some potentially untrusted source (registry key, config file, whatever):

    $FQDN = '" > $null 2>&1; Write-Host -ForegroundColor Green "gotcha!"; #'
    
  • #37793
    Profile photo of Justin King
    Justin King
    Participant

    I never responded to this but thank you: I guess I merely assumed cmd/DOS based programs would not integrate that seamlessly into PowerShell so the "correct" way to do it was to wrap the command into an invoke.

  • #37834
    Profile photo of Warren Frame
    Warren Frame
    Participant

    Hi Justin!

    A good overview of running executables is available here: http://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

    Worth checking out depending on your needs.

    Cheers!

You must be logged in to reply to this topic.