The Effect of SkipPublisherCheck
- Details
- Written by June Blender
- Last Updated: 19 June 2017
- Created: 16 March 2017
- Hits: 20435
The SkipPublisherCheck parameter of the Install-Module cmdlet in PowerShellGet technically affects only the current installation. But, its effect is actually more persistent and involves some security risk. In this article, we'll talk about SkipPublisherCheck and signing modules for PowerShell Gallery.
This article is based on PowerShellGet 1.1.2.0 on Windows PowerShell 5.1.14393.953.
Thanks to Mani Bavandla and Matt Graeber for help with this article.
----------------------
What's the Error?
While creating a new VM in our office, I tried to install a new version of Pester, but got this somewhat familiar error. It says that the version of Pester that we're trying to install (4.0.2) in not digitally signed by its author or publisher.
It ends with a possible fix. If you still want to install this unsigned module, use the SkipPublisherCheck parameter.
PS C:> Install-Module Pester -Force -AllowClobber
PackageManagement\Install-Package : The version '4.0.2' of the module 'Pester' being installed is not catalog signed. Ensure that the version '4.0.2' of the module 'Pester' has the catalog file 'Pester.cat' and signed with the same publisher 'CN=Microsoft Root Certificate Authority 2010, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' as the previously-installed module '4.0.2' with version '3.4.0' under the directory 'C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0'. If you still want to install or update, use -SkipPublisherCheck parameter. ...
But, i was a bit confused, because I had just updated Pester on my dev machine to 4.0.2 and I didn't encounter this error. Instead, Install-Module recognized that the module was unsigned (Is this module signed by Microsoft: 'False'), but it still happily installed it without prompting.
I know that I used SkipPublisherCheck at least once before to install the Pester module, but I didn't realize the it would affect other versions.
Was the effect of SkipPublisherCheck persistent? That is, if I use SkipPublisherCheck once, does PowerShellGet assume that I always want to skip the publisher check?
The answer is technically is "no," but for practical purposes, it's "yes."
The ModuleIsNotCatalogSigned Error
The ModuleIsNotCatalogSigned error is generated only when you try to install or update an unsigned version of a module on a machine on which a signed version of the same module is already installed.
So, two conditions must be satisfied:
- The (newest*) installed version of this module is signed.
- You're trying to install an unsigned version of the same module.
If any other conditions happen, you don't get the error.
It doesn't warn you about an unsigned module when you install a module for the first time. It doesn't warn you when you save a module (Save-Module). It doesn't warn you if you have an older signed version, but a newer installed unsigned version.
Thus, much hinges on whether the newest installed version of the module is signed.
On PowerShell 5.0+, where you can have multiple versions of a module in the same and different directories, PowerShellGet gets doesn't get test the newest installed version or even the newest version in the same path.
Instead, it tests the first the version that Get-Module returns, which is typically the newest version in the CurrentUser path, $home\Documents\WindowsPowerShell\Modules. So, if the newest installed version of the module is signed, but the first version that Get-Module returns is not signed, the error does not trigger.
For example, when I update to Pester 4.0.2, PowerShellGet recognized that the newest installed version was 3.4.5 in AllUsers directory and it installed 4.0.2 there, but, for publisher validation, it tested version 3.4.3 in the CurrentUser ($home) directory.
Finally, the PowerShellGet code doesn't check the module GUID, so PowerShell could test the signature of a different module with the same name, and that would determine whether the signature check is triggered.
Is SkipPublisherCheck Persistent?
Technically, the SkipPublisherCheck parameter affects only the installation in which you use it.
However, because using it installs an unsigned version, and that unsigned version is used for publisher validation, if you use it even once, you won't be warned about unsigned versions of that module again unless you later install a signed version.
Is this module signed?
A valid digital signature indicates that the code in the module was signed by the author or owner and its content has not changed since the signature was applied. This is critical information especially when you're downloading modules from on online site like PowerShell Gallery or other untrusted code repositories.
To detect whether a new or installed module is signed, Install-Module and Update-Module use the Get-AuthenticodeSignature cmdlet in the Microsoft.PowerShell.Security module.
But, what does Get-AuthenticodeSignature look for? An Authenticode signature can take many forms, but in PowerShell modules, it looks for one of the following:
- A digital signature on the module manifest (<ModuleName>.psd1). This guarantees that the manifest has not changed since the owner signed it, but it does not protect any other files.
When the file is signed and the hashes match, the status is Valid and the SignatureType is Authenticode.
- A catalog file (<ModuleName>.cat) in the module root that contains the file hash of multiple files in the module. For best practice, it should include a hash of the module manifest and any file that can include executable code.
When the file is signed and the hashes match, the status is Valid and the SignatureType is Catalog.
- An entry in the system catalog database $env:SystemRoot\System32\CatRoot\<sid>, an on-disk collection of catalog files for Windows components. This feature underlies the system file check that detects and replaces tampered files.
PowerShell files and the files of modules that are installed with Windows are signed by files in the system catalog database.
When the file is signed and the hashes match, the status is Valid and the SignatureType is Catalog.
If a file has both a digital signature and an entry in the module catalog file (e.g. PSScriptAnalyzer.psd1 in 1.11.0), the SignatureType is Authenticode.
Any one of these is sufficient for Install-Module and Update-Module to consider the module to be signed and to notify you if you try to install an unsigned version of the same module.
Can I trust this process?
Of course not. Although the PowerShellGet team has introduced these check to help you, it's always your responsibility to make sure that the modules that you download are safe to run.
The PowerShell Gallery does not make any claims about the effectiveness or safety of any code in the gallery. The code might not run, it might not do what it claims, and the code that you download over insecure channels might be different from the code that was published, even if the manifest file didn't change.
Before running any code from the PowerShell Gallery or any other online source, save the downloaded code in an isolated location (Save-Module, Save-Script). Verify the digital signatures of all signed files. Consider a rule that you'll run only modules in which all files that can contain executable code are catalog-signed and that the signatures are valid.
Then, test every function in the module to make sure that it does all and only what it claims to do.
When publishing a module, use the (new) New-CatalogFile and Test-CatalogFile cmdlets in Microsoft.PowerShell.Security.
And, of course, never run anything on critical that you haven't thoroughly tested in an isolated environment.
For licensed customers, use the forum associated with your product in our Product Support Forums for Registered Customers.
For users of trial versions, please post in our Former and Future Customers - Questions forum.