microsoft / azure-pipelines-tasks

Tasks for Azure Pipelines
https://aka.ms/tfbuild
MIT License
3.42k stars 2.58k forks source link

PowerShell scripts should be signed #16511

Open IAMJDA opened 2 years ago

IAMJDA commented 2 years ago

Required Information

Type: Feature

Enter Task Name: PowerShells should be signed by Microsoft

Issue Description

As a security measure, some companies use AppLocker to restrict PowerShell to constrained language mode. As the PowerShell scripts are not signed, they can't be executed.

Task logs

2022-06-29T14:14:22.3070091Z ============================================================================== 2022-06-29T14:14:22.3070347Z Task : PowerShell on Target Machines 2022-06-29T14:14:22.3070494Z Description : Execute PowerShell scripts on remote machine(s) 2022-06-29T14:14:22.3070626Z Version : 2.0.3 2022-06-29T14:14:22.3070743Z Author : Microsoft Corporation 2022-06-29T14:14:22.3070901Z Help : More Information 2022-06-29T14:14:22.3071057Z ============================================================================== 2022-06-29T14:14:24.2474614Z Deployment started for machine: 'REMOTESERVER.domain.tld:5986' 2022-06-29T14:14:48.0679894Z Deployment logs for Deployment operation on REMOTESERVER.domain.tld:5986 2022-06-29T14:14:48.0701108Z System.AggregateException: 2022-06-29T14:14:48.0701448Z Cannot invoke method. Method invocation is supported only on core types in this language mode. 2022-06-29T14:14:48.0701698Z CategoryInfo :InvalidOperation: (:) [], RuntimeException 2022-06-29T14:14:48.0701908Z FullyQualifiedErrorId :MethodInvocationNotSupportedInConstrainedLanguage 2022-06-29T14:14:48.0702124Z ---> System.Management.Automation.RemoteException: Cannot invoke method. Method invocation is supported only on core types in this language mode. 2022-06-29T14:14:48.0704398Z --- End of inner exception stack trace --- 2022-06-29T14:14:48.0704622Z at Microsoft.VisualStudio.Services.DevTestLabs.Deployment.Deployment.PowershellExecutor.Invoke(String errorContextMessage, Boolean writeResultToLog, Boolean isCancellable) 2022-06-29T14:14:48.0704934Z at Microsoft.VisualStudio.Services.DevTestLabs.Deployment.Deployment.RemoteDeploymentHelper.InstallServiceInternal(String serviceSourcePath, String serviceName, String destinationFileName) 2022-06-29T14:14:48.0705233Z at Microsoft.VisualStudio.Services.DevTestLabs.Deployment.Deployment.RemoteDeploymentHelper.InstallService(String serviceSourcePath, String serviceName, String destinationFileName) 2022-06-29T14:14:48.0705497Z at Microsoft.VisualStudio.Services.DevTestLabs.Deployment.Deployment.DeploymentClient.d__24.MoveNext() 2022-06-29T14:14:48.0705753Z ---> (Inner Exception #0) System.Management.Automation.RemoteException: Cannot invoke method. Method invocation is supported only on core types in this language mode.<--- 2022-06-29T14:14:48.0705897Z 2022-06-29T14:14:48.0705959Z 2022-06-29T14:14:48.0793902Z Deployment status for machine 'REMOTESERVER.domain.tld:5986' : 'Failed' 2022-06-29T14:14:48.1670869Z ##[error], RuntimeException\r\n FullyQualifiedErrorId :MethodInvocationNotSupportedInConstrainedLanguage\r\n"}};] 2022-06-29T14:14:48.2308332Z ##[warning]'##vso[task.logissue type=error;code={"Task_Internal_Error":' contains logging command keyword '##vso', but it's not a legal command. Please reference documentation to fix any potentially syntax error (http://go.microsoft.com/fwlink/?LinkId=817296) 2022-06-29T14:14:48.2309093Z ##vso[task.logissue type=error;code={"Task_Internal_Error": 2022-06-29T14:14:48.2309758Z Cannot invoke method. Method invocation is supported only on core types in this language mode. 2022-06-29T14:14:48.2309947Z CategoryInfo :InvalidOperation: (:) [], RuntimeException 2022-06-29T14:14:48.2310107Z FullyQualifiedErrorId :MethodInvocationNotSupportedInConstrainedLanguage 2022-06-29T14:14:48.2310236Z };] 2022-06-29T14:14:48.4034215Z ##[error] Cannot invoke method. Method invocation is supported only on core types in this language mode. CategoryInfo :InvalidOperation: (:) [], RuntimeException FullyQualifiedErrorId :MethodInvocationNotSupportedInConstrainedLanguage

DmitriiBobreshev commented 2 years ago

@IAMJDA Thanks for reporting! We are working on more prioritized issues now but will get back to this one soon

github-actions[bot] commented 1 year ago

This issue is stale because it has been open for 180 days with no activity. Remove the stale label or comment on the issue otherwise this will be closed in 5 days

IAMJDA commented 1 year ago

Please don't close it... This is important as it's forcing us to lower the IT Security and allow unsigned PowerShell.

github-actions[bot] commented 1 year ago

This issue is stale because it has been open for 180 days with no activity. Remove the stale label or comment on the issue otherwise this will be closed in 5 days

IAMJDA commented 1 year ago

Still not stale...

timbrigham-oc commented 8 months ago

Not stale, this is significant problem. The use of dot sourcing needs to be removed for the same reason.

IAMJDA commented 8 months ago

@DmitriiBobreshev is that improvement placed on any roadmap? IT-Security department is asking when this will be fixed as the security exceptions are only temporary by nature.

DmitriiBobreshev commented 8 months ago

Hi @IAMJDA, I'm sorry but I messed up with a task, seems like you've talked about the PowerShellOnTargetMachines and not the Powershell task, let's ping @rvairavelu, since one of the task owners. My deepest apologies

timbrigham-oc commented 8 months ago

@DmitriiBobreshev, this same issue of unsigned code exists in the PowerShellv2 task and presents in much the same way. My teams use that more then the remoting option.

I would hope that the whole of the tasks using PowerShell would end up signed versus a piecemeal solution for individual tasks.

timbrigham-oc commented 8 months ago

This is an example of using a Powershell@2 task that is just trying to set a variable on a server being deployed to. It's the same issue, the code isn't signed (and therefore receives CLM). It's using an untrusted method invocation and fails the build.

==============================================================================
Task         : PowerShell
Description  : Run a PowerShell script on Linux, macOS, or Windows
Version      : 2.229.4
Author       : Microsoft Corporation
Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/powershell
==============================================================================
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:1 char:1
+ . ([scriptblock]::Create('if ([Console]::InputEncoding -is [Text.UTF8 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage

Cannot invoke method. Method invocation is supported only on core types in this language mode.
timbrigham-oc commented 8 months ago

Apologies for the comment spam, but this is the exact failure from PowerShell@2 on a CLM enabled device.

The issue is deeper then just signing like it initially looked like. You can see that we have code using method invocation being used not within a script file, but being passed directly on the command line, there isn't a script file listed here to whitelist at all. That's expressly not supported by CLM since ownership and intent can't be verified.

##[error]Exit code 1 returned from process: file name 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe', arguments '-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". ([scriptblock]::Create('if ([Console]::InputEncoding -is [Text.UTF8Encoding] -and [Console]::InputEncoding.GetPreamble().Length -ne 0) { [Console]::InputEncoding = New-Object Text.UTF8Encoding $false } if (!$PSHOME) { $null = Get-Item -LiteralPath ''variable:PSHOME'' } else { Import-Module -Name ([System.IO.Path]::Combine($PSHOME, ''Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1'')) ; Import-Module -Name ([System.IO.Path]::Combine($PSHOME, ''Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1'')) }')) 2>&1 | ForEach-Object { Write-Verbose $_.Exception.Message -Verbose } ; Import-Module -Name 'C:\azagent\A1\_work\_tasks\PowerShell_e213ff0f-5d5c-4791-802d-52ea3e7be1f1\2.229.4\ps_modules\VstsTaskSdk\VstsTaskSdk.psd1' -ArgumentList @{ NonInteractive = $true } -ErrorAction Stop ; $VerbosePreference = 'SilentlyContinue' ; $DebugPreference = 'SilentlyContinue' ; Invoke-VstsTaskScript -ScriptBlock ([scriptblock]::Create('. ''C:\azagent\A1\_work\_tasks\PowerShell_e213ff0f-5d5c-4791-802d-52ea3e7be1f1\2.229.4\powershell.ps1'''))"'.

IAMJDA commented 8 months ago

@DmitriiBobreshev Can you please check the newest comments? Seems to be both the remote and local PowerShell task affected.

timbrigham-oc commented 8 months ago

@IAMJDA, for what it is worth, there are actually several related bugs here regarding constrained language mode. My boss gave me permission to submit a bug fix for the ADO agent proper. That was the bug initially biting me for both the local and and remoting powershell commands. Not merged yet, but the changes are here. https://github.com/microsoft/azure-pipelines-agent/pull/4502

My developer team is doing some internal testing now, but the initial round of testing passed for me using their common tooling. Once I got the agent itself patched I've been able to whitelist the script files for the various job types via file hashes. So far I've verified the following: batchscript, cmdline, copyfiles, deletefiles, dotnetcore,nugetauthenticate, nugetcommand, nugettoolinstaller, powershell, powershellontargetmachine, publishbuildartifacts, regexreplace, regextokens.

Official releases of these scripts from MS should 100% still be signed - I hate the fact that I have to add every version of every task to my wdac whitelist - but at least it's progress.