Open deejaybeam opened 1 year ago
We noticed this in https://github.com/microsoft/vscode/issues/157083 originally and just wrapped the script in a try. @joaomoreno any idea how to sign a ps1 file? If I recall right I tried adding it to our sign step and it didn't work.
Alternatively, could you use the Unblock-File
cmdlet to allow shellIntegration.ps1
? See example 7 in https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy
Alternatively, could you use the
Unblock-File
cmdlet to allowshellIntegration.ps1
? See example 7 in https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy
Please read the example 7 again:
The Unblock-File cmdlet unblocks scripts so they can run, but doesn't change the execution policy.
Unblock-File has nothing to do with execution-policy.
The problem is that the execution-policy is set to "AllSigned" via GPO - this way is is NOT possible to change that.
Ah I see, Unblock-File
would work for RemoteSigned
but not AllSigned
or Restricted
.
My understanding is that when "terminal.integrated.shellIntegration.enabled": true
the terminal launch command (without the try()
wrap) is e.g.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe '-noexit' '-command' ' . "c:\LocalPrograms\g2encmck\VSCode\resources\app\out\vs\workbench\contrib\terminal\browser\media\shellIntegration.ps1"'
My computer's ExecutionPolicy is Restricted
, so this does not work. However, I can add the -ExecutionPolicy ByPass
argument and it works:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe '-noexit' '-ExecutionPolicy' 'ByPass' '-command' ' . "c:\LocalPrograms\g2encmck\VSCode\resources\app\out\vs\workbench\contrib\terminal\browser\media\shellIntegration.ps1"'
I think this will also work for AllSigned
, and it would be great to add this for Restricted
users in any case.
Ah I see,
Unblock-File
would work forRemoteSigned
but notAllSigned
orRestricted
.My understanding is that when
"terminal.integrated.shellIntegration.enabled": true
the terminal launch command (without thetry()
wrap) is e.g.C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe '-noexit' '-command' ' . "c:\LocalPrograms\g2encmck\VSCode\resources\app\out\vs\workbench\contrib\terminal\browser\media\shellIntegration.ps1"'
My computer's ExecutionPolicy is
Restricted
, so this does not work. However, I can add the-ExecutionPolicy ByPass
argument and it works:C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe '-noexit' '-ExecutionPolicy' 'ByPass' '-command' ' . "c:\LocalPrograms\g2encmck\VSCode\resources\app\out\vs\workbench\contrib\terminal\browser\media\shellIntegration.ps1"'
I think this will also work for
AllSigned
, and it would be great to add this forRestricted
users in any case.
This seems like a bad idea. The correct solution still consists of having the file become signed properly again. Admittedly however this would still leave a requirement to help with execution policy being set to Restricted, but if anything, such an override should set the policy to AllSigned or RemoteSigned, there's no reason to use Bypass at all in this context. AND such an override is already possible to configure:
https://code.visualstudio.com/docs/terminal/profiles
So I guess your ask is to expose UI toggles for this? If so, that should go into a separate feature request issue, right?
@Tyriar :
When you asked @TylerLeonhardt the same question you asked @joaomoreno about here, in this issue over in the following issue: https://github.com/microsoft/vscode/issues/157083#issuecomment-1206495419
you mentioned that "It's included in our signing job but [doesn't work]". Assuming it contains no secrets, can you please share the step? Anyway, since there's some confusion, I'll try to help:
The example script from https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_signing?view=powershell-7.4 is a bit misleading. Instead you'll probably need something like:
## Signs a file
[cmdletbinding()]
param( #the comments in this block exist to showcase potential but fictional default values one would want to set here instead of initializing them as empty. In that case one might want to comment out the respective mandatory=$true lines
[Parameter(Mandatory=$true)]
[string] $FilePath = '', #= 'c:\scripts\Remodel.ps1',
[Parameter(Mandatory=$true)]
[string] $CertificatePath = '', # = 'Cert:\CurrentUser\My', # note that "Cert:\" is NOT a stand-in for a file system drive letter but instead a reference to the certificate provider drive, see https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/about/about_certificate_provider?view=powershell-7.4
[Parameter(Mandatory=$true)]
[string] $TimestampServer = '' #'https://timestamp.fabrikam.com/scripts/timstamper.dll'
)
$Certificate = Get-ChildItem -Path $CertificatePath -CodeSigningCert
Set-AuthenticodeSignature -FilePath $FilePath -Certificate $Certificate -IncludeChain All -TimestampServer $TimestampServer
which is essentially a refined hybrid of Examples 1 and 3 from https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-authenticodesignature?view=powershell-7.4
Of course, you'll have to manually sign the above script by manually executing the steps from it before you can use it to automatically sign scripts with it as part of CI.
However, this might not be enough to accomplish what you need, not sure how this works internally at MSFT, so, at the risk of overkill, here's a full-blown article series on this:
But it's written from an 'omnipotent'/lab perspective AND from the perspective of publishing for Enterprise-internal users (which will have the Root CA cert of the Internal PKI in their trusted Root CAs store) instead of for Enterprise-external users (which won't, but which WILL have other ones, such as the one you'll indirectly use to sign this, since presumably you won't use a self-signed cert, since that'd make the whole exercise pointless), so, you almost certainly can't 1:1 adapt it, but it should provide some important context one would miss when just reading the docs 'naively'.
This seems like a bad idea. The correct solution still consists of having the file become signed properly again. Admittedly however this would still leave a requirement to help with execution policy being set to Restricted, but if anything, such an override should set the policy to AllSigned or RemoteSigned, there's no reason to use Bypass at all in this context. AND such an override is already possible to configure:
https://code.visualstudio.com/docs/terminal/profiles
So I guess your ask is to expose UI toggles for this? If so, that should go into a separate feature request issue, right?
@no-identd I agree the script should be signed in any case but there should be a solution for restricted
users as well. I think it's about as bad an idea as it is for Anaconda to use it for their prompt and I've never heard any security concerns regarding that. If the signing works then setting it to AllSigned
or RemoteSigned
would be fine too but I don't see a big difference since VSCode is bypassing the ExecutionPolicy for this specific command in any case. I agree this is a separate ask so we can continue the discussion in https://github.com/microsoft/vscode/issues/199122
@no-identd I think this is the call:
Things have changed since I looked at this but I remember adding .ps1 to the list of files to be signed and it didn't seem to work. Unfortunately I don't think this can be fixed/validated externally so it needs someone who knows more about this than me to help out.
@joaomoreno @rzhao271 any help here would be appreciated
Just decided to see what this was about in my AppLocker logs. What's it actually breaking if I don't give it a bypass?
Signing PS1 scripts is fully supported by Microsoft tools, so if it doesn't work for you I'd be raising a bug with your CI support.
For example ...
$cert= Get-PfxCertificate -FilePath $certfile
Set-AuthenticodeSignature -Certificate $cert -HashAlgorithm SHA256 -FilePath $exename
Sticks a huge comment on the end of the script ...
./Get-AppLockerEvents.ps1 -ForwardedEvents > c:\temp\applocker2.csv
# SIG # Begin signature block
# MIIGLgYJKoZIhvcNAQcCoIIGHzCCBhsCAQExDzANBglghkgBZQMEAgEFADB5Bgor
...
# M14pXYkIxEqYOiVDnizAE00+DubW5yEa19ig5n/8cJvVlgYt2mDmWrCoMKQoPD8i
# Cko=
# SIG # End signature block
Future reference: this is where the executables are being signed: https://github.com/microsoft/vscode/blob/74b0694b19996bc247d08855f7222271a51c7456/build/azure-pipelines/cli/cli-win32-sign.yml#L45
DM'd @joaomoreno for some help
Does this issue occur when all extensions are disabled?: Yes
Steps to Reproduce:
This appears since 1.74. I hoped it was just forgotten to sign shellIntegration.ps1, but with current release the issue continues.
We have a company policy to set execution of powershell-scripts via GPO to "AllSigned" so it is not possible to bypass or change the execution-policy on the computer.
We are also monitor this event on our systems which triggers an alert everytime VSCode is started, because of the execution of an unsigned powershell script.
Relevant EventLogs: